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 ;)
gracias!!!
Gracias por la aclaración!
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.
gracias!!
¡Muchas gracias, tu explicación me ayudó a entender ese query!
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.
Ahora valido que obtengo el id del correo duplicado.
SELECT id
FROM(SELECT id,ROW_NUMBER()OVER(PARTITIONBY email ORDERBY 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.
DELETEFROM platzi.alumnoswhere id =(SELECT id
FROM(SELECT id,ROW_NUMBER()OVER(PARTITIONBY email ORDERBY id)AS row
FROM platzi.alumnos)AS duplicados
WHERE duplicados.row>1);
!Genio! Yo por no prestar atención borré todos los registros y tuve que volver al script de sql para insertar toda la info en la tabla xD
¡Ánimo vas por la mitad!
Solucion al reto
DELETEFROM platzi.alumnosWHERE id IN(SELECT id FROM(SELECT*FROM(SELECT id,ROW_NUMBER()OVER(PARTITIONBY nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
ORDERBY id ASC)AS row
FROM platzi.alumnos)AS duplicados
WHERE duplicados.row>1)AS duplicados_id);
Este borra todos todos los valores duplicados, entiendo que debería borrar solo 1 para que se conserve el valor original
Para SQL Server:
--METODO1--MOSTRARDUPLICADOAPARTIRDELIDUSE[platzi]SELECT*FROM platzi.alumnosAS ou
WHERE(SELECTCOUNT(*)FROM platzi.alumnosAS inr
WHERE ou.id= inr.id)>1GO--METODO2--MOSTRARDUPLICADOCOMPARANDOTODOSLOSCAMPOS,EXCEPTOELIDUSE[platzi]SELECTCONCAT(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.alumnosGROUPBYCONCAT(platzi.alumnos.nombre,',', platzi.alumnos.apellido,',', platzi.alumnos.email,',', platzi.alumnos.colegiatura,',', platzi.alumnos.fecha_incorporacion,',', platzi.alumnos.carrera_id,',', platzi.alumnos.tutor_id)HAVINGCOUNT(*)>1ORDERBYCOUNT(*)DESCGO--METODO3--MOSTRARDUPLICADOCOMPARANDOTODOSLOSCAMPOS,EXCEPTOELIDCONSUBCONSULTAUSE[platzi]SELECT*FROM(SELECTROW_NUMBER()OVER(PARTITIONBY nombre,apellido,email,colegiatura, fecha_incorporacion,carrera_id,tutor_id
ORDERBY id ASC)AS row,*FROM platzi.alumnos)AS duplicados
WHERE duplicados.row>1ORDERBY row DESC
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:
Cristian!!! Muchas gracias, lo pude entender! ( :
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:
Gracias por el aporte, muy útil
chat GPT siempre ayudando
Hola, todavía me confundo con los subqueries, me pueden ayudar porfa a entenderlos mejor...
Muchas gracias...
Hola :)
Hay una clase de subqueries en otro de los cursos de SQL que me gusta mucho, me parece súper clara y sencilla.
Te la dejo abajo.
Igual si después de eso tienes dudas o quieres comentar algo, aquí estamos.
Lo más probable es que ya hayas entendido el tema, pero dejo el artículo para futuras generaciones.
P.D: Es en inglés, les servirá para practicar
Alguien me podría explicar el OVER() que función cumple? por fa :)
Primero que nada debes recordar que el proposito de row_number es asignar un numero a cada fila, empezando desde 1 y avanzando de 1 en 1.
Over le indica a la función row_number sobre cuál grupo de registros hacer la numeración de las filas. imagina que tienes una base de datos (BD) con 100 registros de ciudades y se repiten siempre 3 ciudades, con over (partitition by city) habrá una agrupación por ciudad, es decir, tendras 3 grupos de registros sobre los cuales hacer la numeración.
Si no pusieras nada en over() simplemente numerarías de nuevo toda la base de datos pues no habría un criterio sobre el cual partir la BD.
Gracias Juan. Tu comentario aclaro mis dudas.
Para entender de manera mas simple lo que esta pasando en el ultimo query, les recomendo que corran esta query:
SELECT*,ROW_NUMBER()OVER(PARTITIONBY colegiatura)AS row
FROM platzi.alumnos;
Asi se dan cuenta como funciona a menor escala para luego interpretar lo demas, espero ser de ayuda!
Este es el comentario que me salvo!
15. Duplicados
SELECT*FROM platzi.alumnos AS ou
WHERE(SELECTCOUNT(*)FROM platzi.alumnos AS inr
WHERE ou.id = inr.id
)>1;SELECT(platzi.alumnos.*)::text,COUNT(*)FROM platzi.alumnos
GROUPBY platzi.alumnos.*HAVINGCOUNT(*)>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
GROUPBY platzi.alumnos.nombre, platzi.alumnos.apellido, platzi.alumnos.email, platzi.alumnos.colegiatura, platzi.alumnos.fecha_incorporacion, platzi.alumnos.carrera_id, platzi.alumnos.tutor_id
HAVINGCOUNT(*)>1;SELECT*FROM(SELECT id, ROW_NUMBER()OVER(PARTITIONBY nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
ORDERBY id ASC)ASrow,*FROM platzi.alumnos
)AS duplicados
WHERE duplicados.row>1;
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
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.alumnosgroup by(nombre,apellido,email)order by cantidad desc```
Hola a todos:
En mi caso le apliqué una pequeña modificación para realizar la agrupación (sección GROUP BY), como se asigna el nombre "items" al conjunto de datos requeridos, ese nombre es el utilizado para agrupar por el conjunto de campos.
A continuación, un ejemplo:
SELECT( nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
):: text AS items,COUNT(id):: integer AS cantidad
FROM platzi.alumnosGROUPBY items
HAVINGCOUNT(*)>1;
Nota: En el SELECT se utilizó el campo <<id>> únicamente para mejorar la visualización en la plataforma de Platzi. En pgadmin o consola se puede usar el caracter (*).
Ejercicio cumplido...
DELETEFROM platzi.alumnosWHERE id IN(SELECT id
FROM(SELECT id,ROW_NUMBER()over(PARTITIONBY nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id
ORDERBY id ASC)AS row
FROM platzi.alumnos)AS duplicados
WHERE duplicados.row>1);```
vaya nivel de abstracción! yo aún no digiero bien los subqueries
Si no entendiste el último código, no te preocupes. Creo que el profesor se emocionó un poco y se adelantó con la teoría 😅.
Te dejo un video que me ayudó a introducirme en las funciones de ventana:
No entendí muy bien la funcionalidad de los '::' , o sea entiendo para que sirven en este caso pero no como se podrían usar en otras aplicaciones o cual es su finalidad
Es para hacer la comparativa mas facil, ya que es solo texto