Pregunta 1Cuando especificas GROUP BY name, ¿cuántas filas tiene el resultado (tabla score / 10 nombres distintos)?
GROUP BY y HAVING — Agregados por grupo
Aprende SQL GROUP BY y HAVING: agregados por grupo, filtrar grupos con HAVING y en qué se diferencia de WHERE — practicando con datos de notas en CSV, en vivo en tu navegador.
Los datos usados en este artículo — la tabla score
En el artículo anterior redujiste una tabla entera a un solo valor. El `GROUP BY` de este artículo (agrupación — reunir en un mismo grupo las filas que comparten el mismo valor) ejecuta los agregados por grupo y devuelve una fila de agregado por grupo. Además, `HAVING` te permite filtrar los resultados de agregado, como «solo los grupos cuyo promedio sea 80 o más».
El tema es la misma tabla score que la vez anterior (30 filas = 10 personas × 3 materias). Agrupar por name da 10 grupos, y agrupar por subject da 3 grupos.
GROUP BY — agregar por grupo
Cuando escribes GROUP BY columna, las filas que comparten el mismo valor en esa columna se reúnen en un mismo grupo, y las funciones de agregado se calculan una vez por grupo. Con SELECT name, AVG(score) FROM score GROUP BY name;, las 3 filas con el mismo nombre (una por materia) forman un grupo, y obtienes una fila de promedio por nombre. Las únicas «columnas planas» que puedes poner en SELECT son las columnas nombradas en `GROUP BY`; cualquier otra columna tiene que ir envuelta en una función de agregado (porque su valor no es único dentro de un grupo).
AVG(score) se calcula por grupo. Con 10 personas, el resultado son 10 filas.-- Cantidad / promedio / nota más alta por materia (3 grupos por subject)
SELECT
subject,
COUNT(*) AS row_count,
ROUND(AVG(score), 1) AS avg_score,
MAX(score) AS top_score
FROM score
GROUP BY subject;
HAVING — filtrar los resultados de agregado
Tras un agregado de grupo, a veces quieres filtrar sobre el valor de agregado, como «muestra solo los grupos cuyo promedio sea 80 o más». No puedes hacer esto con WHERE. WHERE es una cláusula que juzga las filas individuales antes de la agrupación, así que un agregado de grupo como AVG(score) aún no se ha calculado. Ahí es donde entra `HAVING`. HAVING se escribe después de GROUP BY y juzga su condición sobre los resultados de agregado de los grupos. Escribir HAVING AVG(score) >= 80 conserva solo los grupos cuyo promedio es 80 o más.
GROUP BY agrega en 10 grupos, luego HAVING AVG(score) >= 80 juzga los grupos ya agregados y conserva solo los que satisfacen la condición.-- Solo los nombres cuyo promedio supera 85 (HAVING juzga el valor de agregado)
SELECT
name,
ROUND(AVG(score), 2) AS avg_score
FROM score
GROUP BY name
HAVING AVG(score) > 85;
WHERE vs. HAVING — filtrar filas, o filtrar grupos
WHERE y HAVING son ambos filtros, pero actúan en momentos distintos. WHERE juzga las filas individuales y las descarta antes de la agrupación. HAVING juzga por grupo y los descarta después de agrupar y agregar. El orden de ejecución es FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY.
También puedes usar ambos a la vez. En ese caso el flujo es «restringir las filas objetivo con WHERE, luego agrupar, luego filtrar los resultados de agregado con HAVING». Por ejemplo, para obtener «las personas cuyo promedio por nombre sea 80 o más, considerando solo Math y English», restringes las filas con WHERE subject IN ('Math','English') y restringes los grupos con HAVING AVG(score) >= 80.
WHERE juzga las filas sobre columnas planas y las descarta antes de la agrupación, mientras que HAVING juzga los grupos sobre valores de agregado (AVG, etc.) y los descarta después de la agrupación. El punto clave es dónde se descartan las cosas. Ejemplo: WHERE subject='Math' (filtra filas) y HAVING AVG(score)>=80 (filtra grupos).-- Usar WHERE y HAVING juntos
-- Excluir Science, conservar solo los nombres cuyo promedio sea 80 o más
SELECT
name,
ROUND(AVG(score), 2) AS avg_two
FROM score
WHERE subject <> 'Science'
GROUP BY name
HAVING AVG(score) >= 80;
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2Cuando quieres extraer «solo las personas cuyo promedio por nombre sea 80 o más», ¿en qué cláusula va la condición de 80 o más?
Pregunta 3¿Qué afirmación describe correctamente la diferencia entre WHERE y HAVING?