Query Ejercicio:
insert into platzi.alumnos (id, nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id) values (1000, 'Pamelina', null, '[email protected]', 4800, '2020-04-26 10:18:51', 12, 16);
Introducción a SQL
Breve historia de SQL
Álgebra relacional
Instalación de la BD de ejemplo
Qué es una proyección (SELECT)
Origen (FROM)
Productos cartesianos (JOIN)
Selección (WHERE)
Ordenamiento (ORDER BY)
Agregación y limitantes (GROUP BY y LIMIT)
Ejercitando tu SQL
El primero
El segundo más alto
Seleccionar de un set de opciones
En mis tiempos
Seleccionar por año
Duplicados
Selectores de rango
Eres lo máximo
Egoísta (selfish)
Resolviendo diferencias
Todas las uniones
Triangulando
Generando rangos
Regularizando expresiones
Conceptos de SQL Avanzado
Bases de datos distribuidas
Queries distribuídos
Sharding
Window functions
Particiones y agregación
El futuro de SQL
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Query de inserción
insert into platzi.alumnos (id, nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id) values (1001, 'Pamelina', null, '[email protected]', 4800, '2020-04-26 10:18:51', 12, 16)
Aportes 212
Preguntas 17
Query Ejercicio:
insert into platzi.alumnos (id, nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id) values (1000, 'Pamelina', null, '[email protected]', 4800, '2020-04-26 10:18:51', 12, 16);
La cláusula HAVING es una implemetacion que el sistema gestor de bases de datos SQL crea para complementar el condicionante WHERE, ya que el condicionante WHERE no permite utilizar funciones de agregación como SUM, MAX, MIN o AVG, es decir, con un condicionante WHERE no podemos crear consultas válidas que sean capaz de devolvernos los datos de los clientes que compraron más de 1000 productos durante un año, por ejemplo.
Tener esto en cuenta por si tampoco entendieron nada y este es su primer curso de base de datos 😉
Saludos, mi respuesta:
En el ejercicio de encontrar un DUPLICADO, se está haciendo una partición de la tabla de todos los valores en filas de cada una de las variables o columnas de la tabla a excepción del id, el cual no puede ser igual y no se repite al ser una primary key.
Cuando se aplica esta partición en cada valor se hace único los valores, es decir, cada row viene siendo una partición, y al utilizar la función agregada que en este caso es ROW_NUMBER() va a contar los valores de cada una de las particiones haciendo que se reinicie los “números de fila” cuando salta de partición en partición. por eso, cuando encuentra dos valores iguales, enumera los dos valores, dejando como valor en su row un 2.
Más información del having => https://www.postgresqltutorial.com/postgresql-having/
Por si necesitan el código para insertar una fila
insert into platzi.alumnos (id, nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id) values (1001, 'Pamelina', null, '[email protected]', 4800, '2020-04-26 10:18:51', 12, 16);
¡Ánimo vas por la mitad!
Solucion al reto
DELETE
FROM platzi.alumnos
WHERE id IN (SELECT id FROM (
SELECT *
FROM (SELECT id, ROW_NUMBER() OVER(
PARTITION BY
nombre, apellido,
email, colegiatura,
fecha_incorporacion, carrera_id,
tutor_id
ORDER BY id ASC) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1) AS duplicados_id);
Por lógica no puede existir 2 correos iguales, por lo tanto realice la actividad en base a eso
SELECT email,COUNT(*)
FROM platzi.alumnos
GROUP BY email
HAVING COUNT(*) > 1;
De esa forma obtuve el nombre del correo repetido, en base a ello, se que puedo realizar la agrupación por partición utilizando unicamente el correo.
SELECT id
FROM (
SELECT id, ROW_NUMBER() OVER(PARTITION BY email ORDER BY id) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1;
Una vez certificado que obtengo el id del dato duplicado, procedo a borrar el registro.
DELETE FROM platzi.alumnos
where id = (
SELECT id
FROM (
SELECT id, ROW_NUMBER() OVER(PARTITION BY email ORDER BY id) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
);
Para SQL Server:
-- METODO 1
-- MOSTRAR DUPLICADO A PARTIR DEL ID
USE [platzi]
SELECT *
FROM platzi.alumnos AS ou
WHERE
(
SELECT COUNT(*)
FROM platzi.alumnos AS inr
WHERE ou.id = inr.id
) > 1
GO
-- METODO 2
-- MOSTRAR DUPLICADO COMPARANDO TODOS LOS CAMPOS, EXCEPTO EL ID
USE [platzi]
SELECT CONCAT(platzi.alumnos.nombre,',',
platzi.alumnos.apellido,',',
platzi.alumnos.email,',',
platzi.alumnos.colegiatura,',',
platzi.alumnos.fecha_incorporacion,',',
platzi.alumnos.carrera_id,',',
platzi.alumnos.tutor_id), COUNT(*)
FROM platzi.alumnos
GROUP BY CONCAT(platzi.alumnos.nombre,',',
platzi.alumnos.apellido,',',
platzi.alumnos.email,',',
platzi.alumnos.colegiatura,',',
platzi.alumnos.fecha_incorporacion,',',
platzi.alumnos.carrera_id,',',
platzi.alumnos.tutor_id)
HAVING COUNT(*) >1
ORDER BY COUNT(*) DESC
GO
-- METODO 3
-- MOSTRAR DUPLICADO COMPARANDO TODOS LOS CAMPOS, EXCEPTO EL ID CON SUBCONSULTA
USE [platzi]
SELECT *
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY nombre,apellido,email,colegiatura,
fecha_incorporacion,carrera_id,tutor_id
ORDER BY id ASC) AS row, *
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
ORDER BY row DESC
Para los que usan MySQL Workbench, pueden encontrar los duplicados usando CONCAT_WS de la siguiente forma :
Por si quieren entender mejor como funciona el PARTITION BY, me sirvió mucho para comprender:
Para encontrar duplicados basados en sus datos principales: nombre, apellido y email.
select (nombre,apellido,email)::text as datos_usuarios, count(*) as cantidad
from platzi.alumnos
group by (nombre,apellido,email)
order by cantidad desc```
Ejercicio cumplido…
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() over(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
)AS row
FROM platzi.alumnos
)AS duplicados
WHERE duplicados.row > 1);```
Soy bastante nuevo en este mundo así que tuve que hacer una especie de corrida en frío para entenderlo y poder crear una imagen en mi cabeza de lo que sucede en las subconsultas. Dejo esto que es lo que veo en mi mente sobre el código de la case por si a alguien le sirve. Me corrigen los expertos por fa c:
Para entender de manera mas simple lo que esta pasando en el ultimo query, les recomendo que corran esta query:
SELECT *, ROW_NUMBER() OVER(PARTITION BY colegiatura) AS row
FROM platzi.alumnos;
Asi se dan cuenta como funciona a menor escala para luego interpretar lo demas, espero ser de ayuda!
No me sirvieron los ejemplos en workbench 😦
Solución al reto anterior
SELECT *
FROM (
SELECT *,
DATE_PART('YEAR', fecha_incorporacion) AS anio_incorporacion,
DATE_PART('MONTH', fecha_incorporacion) AS mes_incorporacion
FROM platzi.alumnos
) AS alumnos_con_anio
WHERE anio_incorporacion = 2018 AND mes_incorporacion = 5;```
mismo resultado mucho mas fácil:
select nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id, count(nombre)
from platzi.alumnos
group by nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
having count()>1
La solucion en MySQL WorkBench seria:
<SELECT *
FROM (
SELECT *, YEAR(fecha_incorporacion) AS Ano, MONTH(fecha_incorporacion) AS Mes
FROM platzi.alumnos
) AS Fechas
WHERE Ano=2018 AND Mes=5;>
Mi solución al reto (postgreSQL):
DELETE FROM platzi.alumnos
WHERE id IN(
SELECT table_alumnos.id
FROM (
SELECT
ROW_NUMBER() OVER(
PARTITION BY
a1.nombre,
a1.apellido,
a1.email,
a1.colegiatura,
a1.fecha_incorporacion,
a1.carrera_id,
a1.tutor_id
ORDER BY a1.id ASC
) AS row_alumnos, a1.*
FROM platzi.alumnos as a1
) AS table_alumnos
WHERE table_alumnos.row_alumnos>1
)
SELECT *
FROM platzi.alumnos AS ou
WHERE (
SELECT COUNT(*)
FROM platzi.alumnos AS inr
WHERE ou.id = inr.id
) > 1;
SELECT (platzi.alumnos.*)::text, COUNT(*)
FROM platzi.alumnos
GROUP BY platzi.alumnos.*
HAVING COUNT(*) > 1;
SELECT (
platzi.alumnos.nombre,
platzi.alumnos.apellido,
platzi.alumnos.email,
platzi.alumnos.colegiatura,
platzi.alumnos.fecha_incorporacion,
platzi.alumnos.carrera_id,
platzi.alumnos.tutor_id
)::text, COUNT(*)
FROM platzi.alumnos
GROUP BY platzi.alumnos.nombre,
platzi.alumnos.apellido,
platzi.alumnos.email,
platzi.alumnos.colegiatura,
platzi.alumnos.fecha_incorporacion,
platzi.alumnos.carrera_id,
platzi.alumnos.tutor_id
HAVING COUNT(*) > 1;
SELECT *
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
)AS row,
*
FROM platzi.alumnos
)AS duplicados
WHERE duplicados.row > 1;
soluciòn para eliminar el campo duplicado
DELETE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER () OVER (
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row >1);
-- Tarea -> Eliminar los duplicados de la tabla platzi.alumnos
DELETE
FROM platzi.alumnos
WHERE id IN (SELECT id
FROM (
SELECT --id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS ROW, *
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1);
Lo que paso en el último query fue que en vez de contar los rows, como lo solíamos hacer, ahora los estamos separando de acuerdo a ciertas características especificadas en la Partición. Eso significa que ahora cada row con un name, email, lastname, career_id, tutor_id, etc.
único van a tener un valor de 1 en la columna row. Cada vez que haya otra tupla igual, ese valor va a aumentar en uno
Para la tarea ocupé los dos métodos mezclados, tal vez en la práctica nada recomendado pero para fines de practicar me pareció útil.
SELECT *
FROM platzi.alumnos
WHERE(EXTRACT(MONTH FROM fecha_incorporacion)) = 05
and
(DATE_PART('YEAR', fecha_incorporacion)) = 2018
;```
Solucion:
DELETE
FROM platzi.alumnos
WHERE id IN (SELECT id FROM (
SELECT *
FROM (SELECT id, ROW_NUMBER() OVER(
PARTITION BY
nombre, apellido,
email, colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1) AS duplicados_id);
Ejercicio de tarea:
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
);
Reto resuelto, bastante intuitivo.
DELETE FROM alumnos
WHERE id IN (
SELECT id FROM (SELECT ROW_NUMBER() OVER(PARTITION BY nombre,apellido,email,colegiatura,fecha_incorporacion,carrera_id,tutor_id ORDER BY id) AS count_row,
* FROM alumnos) AS duplicados
WHERE count_row > 1
)
Mi solucion al ejercicio:
Después de tantos intentos pude entenderle, esta es mi solución:
-- Eliminar duplicados con subquery
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
)AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1);
Solución al reto:
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER (
PARTITION BY nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
ORDER BY id
) AS row_num
FROM platzi.alumnos
) AS subquery
WHERE subquery.row_num > 1
);
mi aporte
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER (
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicado
WHERE duplicado.row > 1
);
Mi solución
DELETE FROM platzi.alumnos
WHERE id=(
SELECT id
FROM (
SELECT id ,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row>1);
SQL SERVER
De esta forma puedo eliminar mas de un registro duplicado a la vez
DECLARE @DuplicateIds VARCHAR(MAX);
SELECT @DuplicateIds = STRING_AGG(Id, ',') WITHIN GROUP (ORDER BY Id)
FROM (
SELECT Id,
ROW_NUMBER() OVER (
PARTITION BY Nombre, Apellido, Email ORDER BY Id ASC
) AS row
FROM Platzi.Alumnos
) AS Duplicados
WHERE Duplicados.row > 1;
SELECT @DuplicateIds
DELETE FROM Platzi.Alumnos WHERE Id IN (SELECT VALUE FROM string_split(@DuplicateIds, ','));
Reto de la clase
DELETE FROM alumnos
WHERE id IN (
SELECT id FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY nombre,apellido, email, colegiatura,
fecha_incorporacion, carrera_id, tutor_id
ORDER BY id ASC) row,id
FROM alumnos
) duplicados
WHERE row > 1
)
-- Otra forma
DELETE FROM alumnos
WHERE id IN
(
SELECT MAX(id) FROM alumnos
GROUP BY nombre,apellido,email,colegiatura,fecha_incorporacion, carrera_id, tutor_id
HAVING COUNT(id) > 1
)
Esta fue mi solución:
SELECT nombre,fecha_incorporacion
FROM alumnos
WHERE ( EXTRACT(YEAR FROM fecha_incorporacion)=2018 AND EXTRACT(MONTH FROM fecha_incorporacion)=05);
Creo yo, que esto es bueno de p´ractica, pero si ya estamos en un trabajo , o nosotros iniciamos la DB de algún trabajo, creo que la mayoria de cosas tienen un identificador único, entonces esta practica es algo exagerada, pero es bueno que la sepamos, en casos extremos.
Por dar ejemplo una persona tiene su DNI (En México seria tu INE, donde tienes un número único que te identifica como persona), un auto tiene un no. serie, una laptop también, aunque entiendo que aún así puede haber error de dedo, lo prudente seria que si vas entrando hagas un chequeo al Datatype de cada tabla, y saber si ya tienen configurado el Unique en alguna columna, sino, primero verifica duplicados con estos comandos que vimos y luego activa en alguna columna prudente el Unique, así si alguien más ingresa un dato duplicado, ya sea error de dedo o intencional, lo botará porque ya existe uno, haciendo así una revisión más fácil de los demás datos, pues ya tienes un gran filtro de seguridad anti duplicado.
Casi que no!
Reto: ¿Cómo se realiza el borrado del dúplicado de esta tabla con esta ultmina versión del query?
DELETE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1);
Eliminar filas duplicadas en modo hardcore:
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
);
Mis soluciones del reto
-- Traemos solo los usuarios que se incorporaron en mayo del 2018
SELECT *
FROM PLATZI.ALUMNOS
WHERE (DATE_PART("YEAR", FECHA_INCORPORACION)) = 2018
AND (DATE_PART("MONTH", FECHA_INCORPORACION)) = 5;
-- Otra solución
SELECT *
FROM PLATZI.ALUMNOS
WHERE (EXTRACT(YEAR
FROM FECHA_INCORPORACION) = 2018) AND( EXTRACT (MONTH
FROM FECHA_INCORPORACION)= 5 );
La forma en que yo lo hice
SELECT nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
from platzi.alumnos
group by nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
having count(*)>1;
Aqui tengo la respuesta:
SELECT *
FROM platzi.alumnos
WHERE(EXTRACT(YEAR FROM fecha_incorporacion)) = 2019;
SELECT *
FROM platzi.alumnos
WHERE(DATE_PART('MONTH', fecha_incorporacion)) = 05;
SELECT *
FROM platzi.alumnos
WHERE(EXTRACT(DAY FROM fecha_incorporacion)) = 18;
que les parece 😁
SELECT * FROM (
SELECT *, DATE_PART('YEAR',fecha_incorporacion) AS anio_incorporacion,
DATE_PART('MONTH',fecha_incorporacion) AS mes_incorporacion
FROM platzi.alumnos
)AS alumnos_con_anio
WHERE anio_incorporacion = 2019 and mes_incorporacion = 05;
Select *
from platzi.alumnos
where (extract(YEAR FROM fecha_incorporacion)) = 2018 and
(extract(MONTH FROM fecha_incorporacion)) = 5;
Como opinión personal creo que es una sesión con bastantes elementos para haberla desarrollado en una sola clase, la verdad me resultó bastante complejo entender el código y su funcionalidad predisamente por la cantidad de elementos que trae, lo digo como alguien que apenas está aprendiendo SQL
Mi resolución al reto:
DELETE FROM platzi.alumnos
WHERE platzi.alumnos.id IN (
SELECT id
FROM (
SELECT
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row,
*
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
);
DELETE
FROM platzi.alumnos AS ou
WHERE (
SELECT COUNT(*)
FROM platzi.alumnos AS inr
WHERE ou.id = inr.id
) > 1;
select (nombre,apellido,email,colegiatura,fecha_incorporacion,carrera_id,tutor_id)::text as conta, count() from platzi.alumnos
group by conta HAVING COUNT()>1
Bueno yo lo haría así
SELECT nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id,
count(*)
FROM platzi.alumnos
GROUP BY nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
HAVING count(*)>1;
–Reto
SELECT *
FROM (
SELECT *,
DATE_PART(‘YEAR’, fecha_incorporacion) AS anio_incorporacion,
DATE_PART(‘MONTH’, fecha_incorporacion) AS mes_incorporacion
FROM platzi.alumnos
) AS alumnos_con_anio
WHERE anio_incorporacion = 2018 AND mes_incorporacion = 05;
DELETE
FROM platzi.alumnos
WHERE id IN ( SELECT id FROM (
SELECT *
FROM (SELECT id, ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1) AS duplicado);
select * from (
SELECT *,EXTRACT(year FROM fecha_incorporacion) as anio,EXTRACT(month FROM fecha_incorporacion) as mes from platzi.alumnos
) as tablaconanio
where anio= 2018 and mes=05
Que salto gigante esta clase
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id FROM(SELECT ROW_NUMBER() OVER(PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos) AS duplicados
WHERE duplicados.row > 1);
SELECT * FROM platzi.alumnos
WHERE (EXTRACT (YEAR FROM fecha_incorporacion) )= 2018
and (extract (month from fecha_incorporacion))=05;
select * FROM (
select *, date_part (‘YEAR’, fecha_incorporacion) as anio_incorp,
date_part (‘MONTH’, fecha_incorporacion) as mes_incorp
FROM platzi.alumnos)
as alumnos_con_anio_mes
where anio_incorp=2018
and mes_incorp=05;
el ORDER BY id ASC dentro de la subquery es importante ya que va a ser el encargado de mostrate el id correcto (1001). Cuando no es colocado el ORDER mostrara el 1000 y si bien estaria marcando un duplicado, no estaria marcando el ultimo registro duplicado
DELETE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id, ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id) AS row_number
FROM platzi.alumnos
) AS duplicates
WHERE duplicates.row_number > 1
);
RETO
DELETE
FROM platzi.alumnos
WHERE id in (SELECT id
FROM (SELECT --id,
ROW_NUMBER() OVER(
PARTITION BY
nombre, apellido,email,colegiatura, fecha_incorporacion,
carrera_id,tutor_id
ORDER BY id ASC
)AS row,
*
FROM platzi.alumnos
)AS duplicado
WHERE duplicado.row >1)
Mi solucion para borrar datos duplicados
delete
from platzi.alumnos
where id in(Select id
from(
select *,
row_number() over(
partition by
nombre, apellido, email,colegiatura,
fecha_incorporacion,carrera_id,tutor_id
order by id asc
)as row from platzi.alumnos
)as duplicado
where duplicado.row>1)
Otra solución para encontrar los duplicados:
SELECT
Cast (nombre as VARCHAR(50))
|| coalesce(cast(apellido as VARCHAR(50)), ’ ')
|| cast (email as VARCHAR(50))
|| cast (colegiatura as FLOAT)
|| cast (fecha_incorporacion as VARCHAR(50))
|| cast (carrera_id as INT)
|| cast (tutor_id as INT)
,Count()
from platzi_alumnos
group by 1
HAVING COUNT () > 1
Mi solución al reto fue:
DETELE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row >1);
SELECT * FROM platzi.alumnos
WHERE (EXTRACT(YEAR FROM fecha_incorporacion))= 2020
AND (EXTRACT(MONTH FROM fecha_incorporacion))=6
Comparto mi manera de solucionar el reto, por si a alguien le sirve 😃:
delete
FROM platzi.alumnos AS A
USING (SELECT ROW_NUMBER () OVER (PARTITION BY nombre, apellido,email,colegiatura,fecha_incorporacion,
carrera_id, tutor_id ORDER BY id ASC) AS Row, *
FROM platzi.alumnos) AS DUPLICADOS
WHERE (A.id = DUPLICADOS.id) AND DUPLICADOS.Row > 1;
SELECT apellido,nombre,email,COUNT()
FROM platzi.alumnos
GROUP BY apellido, nombre, email
HAVING COUNT() > 1;
encontrado por 3 campos iguales
así es como solucione el reto la sentencia with te permite hacer tablas temporales que hacen mas facil de leer el codigo
WITH duplicados as (
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id asc
) AS row,
*
FROM platzi.alumnos
) duplicados
WHERE duplicados.row > 1
)
DELETE FROM platzi.alumnos as al
WHERE al.id in (
SELECT id from duplicados
)
Sí quisieras tener los duplicados de la columna ID más rápido (20 ms menos). Utiliza JOIN y GROUP BY antes que WHERE solo. Aquí el código:
SELECT *
FROM platzi.alumnos AS foo
JOIN (
SELECT id, COUNT(*) AS counter
FROM platzi.alumnos
GROUP BY id
) AS bar
ON foo.id = bar.id
WHERE counter != 1;
DELETE FROM platzi.alumnos
WHERE id IN
(
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id asc
) AS row
FROM platzi.alumnos
) duplicados
WHERE duplicados.row > 1
);
Doble punto equivalente a un "cast" convertir estos campos en un texto
Rara vez vamos a poder encontrar un duplicado por el "id" debido a que este es consecutivo por ende es algo dificil que se repitan aun asi la informacion sea la misma.
Creo que la clase de windows functions debió ponerse al principio del curso para saber realmente como funciona el código que usamos y no simplemente copiar del profesor.
delete from platzi.alumnos where id =(
select id
from (
select row_number() over(
partition by nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
order by id asc
)as row,
*
from platzi.alumnos
)as duplicados
where duplicados.row>1
);
Tarea de la clase anterior
select
fecha_incorporacion
from platzi.alumnos
where date_part('MONTH', fecha_incorporacion) = 05
AND date_part('YEAR', fecha_incorporacion) = 2018
SELECT * FROM platzi.alumnos AS ou
WHERE (
SELECT COUNT(email)
FROM platzi.alumnos AS inr
WHERE ou.email = inr.email
) > 1;
Bueno del ejercicio dado la clase anterior aporto mi respuesta
select *
from platzi.alumnos
where (extract (year from fecha_incorporacion)) =2018
and (extract (month from fecha_incorporacion)) =05;
** RETO**
Borrar los registros duplicados de la tabla alumnos, se debe mantener el primer id registrado.
DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT ROW_NUMBER() OVER(
PARTITION BY
a1.nombre,
a1.apellido,
a1.email,
a1.colegiatura,
a1.fecha_incorporacion,
a1.carrera_id,
a1.tutor_id
ORDER BY id ASC) orden, a1.*
FROM platzi.alumnos a1
) data_alumnos_row
WHERE orden > 1
);
select * from (
select *, date_part(‘YEAR’,fecha_incorporacion)as anio_inc,
date_part(‘MONTH’,fecha_incorporacion)as mes_inc from alumnos) as alumnos_anio
where anio_inc = 2018 and mes_inc = 5
DELETE FROM (
platzi.alumnos
WHERE id IN(
SELECT id
FROM (
SELECT id, ROW_NUMBER () OVER(
PARTITION BY nombre, apellido, email
ORDER BY id ASC)
AS ROW_NUM
FROM platzi.alumnos) AS doble
WHERE ROW_NUM>1);
Con esta pequeña modificación se puede insertar varias veces sin que tengamos problemas con el id
insert into platzi.alumnos (id, nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id) values ((select max (id+1) from platzi.alumnos), 'Pamelina', null, '[email protected]', 4800, '2020-04-26 10:18:51', 12, 16)
Hola! de esta manera borré los duplicados del ejercicio propuesto:
DELETE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT
id
,ROW_NUMBER() OVER(
PARTITION BY
nombre
,apellido
,email
,colegiatura
,fecha_incorporacion
,carrera_id
,tutor_id
ORDER BY id asc
) AS row
FROM platzi.alumnos
) duplicados
WHERE duplicados.row > 1
)
SELECT *
FROM (
SELECT *,
DATE_PART(‘YEAR’, fecha_incorporacion) AS anio_incorporacion,
DATE_PART(‘MONTH’,fecha_incorporacion) AS mes_incorporacion
FROM platzi.alumnos
) AS alumnos_con_anio_mes
WHERE anio_incorporacion = 2018 and mes_incorporacion = 5;
SQL SERVER
Ver duplicados
SELECT
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id,
COUNT()
FROM
alumnos
GROUP BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
HAVING COUNT() > 1
SQL SERVER
Actualización de los últimos dos registros:
UPDATE alumnos
SET nombre = ‘Elwin’, apellido = ‘Leamy’, email = ‘[email protected]’,
colegiatura = 2300, fecha_incorporacion = ‘2021-09-02’, carrera_id = 8,
tutor_id = 12
WHERE id in (999,1000)
SQL SERVER
Solución “Seleccionar por año”
SELECT *
FROM (
SELECT
YEAR(fecha_incorporacion) AS año,
MONTH(fecha_incorporacion) AS mes
FROM alumnos
) AS reto
WHERE reto.año = 2020 AND reto.mes = 05
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.