Agrupación y agregación (GROUP BY, HAVING)
Resumir datos con COUNT, SUM, AVG, MIN y MAX; agrupar con GROUP BY y filtrar grupos con HAVING.
1. Funciones de agregación
Las funciones de agregación toman muchas filas y devuelven un único valor que las resume. Son la base de cualquier reporte.
| Función | Qué calcula |
|---|---|
| COUNT | Cuenta filas. COUNT(*) cuenta todas |
| SUM | Suma los valores de una columna |
| AVG | Promedio de una columna |
| MIN | El valor más pequeño |
| MAX | El valor más grande |
SELECT
COUNT(*) AS total,
AVG(SALARIO) AS promedio,
MIN(SALARIO) AS minimo,
MAX(SALARIO) AS maximo
FROM empleados;Detalle
COUNT(*) cuenta todas las filas; COUNT(columna) ignora los valores NULL de esa columna.2. GROUP BY: resumir por categoría
GROUP BY calcula el resumen por cada grupo de valores: devuelve una fila por categoría. La regla clave es que toda columna del SELECT que no esté dentro de una función de agregación debe aparecer en el GROUP BY.
SELECT CARGO, COUNT(*) AS cantidad
FROM empleados
GROUP BY CARGO;
SELECT UBICACION, COUNT(*) AS cant
FROM mascotas
GROUP BY UBICACION
ORDER BY cant DESC;Traducción mental
Cuando la pregunta dice «cuántos… por…» casi siempre esCOUNT + GROUP BY.3. Agrupar por varias columnas
Se puede agrupar por la combinación de varias columnas: se obtiene una fila por cada combinación distinta de valores.
SELECT ESPECIE, SEXO, COUNT(*) AS cantidad
FROM mascotas
GROUP BY ESPECIE, SEXO
ORDER BY ESPECIE, SEXO;4. WHERE vs HAVING
Es la distinción más importante de la clase. WHERE filtra filas antes de agrupar; HAVING filtra grupos después de agregar y puede usar funciones como COUNT o AVG.
| WHERE | HAVING | |
|---|---|---|
| Cuándo actúa | Antes de agrupar | Después de agrupar |
| Filtra | Filas individuales | Grupos ya formados |
| ¿Usa COUNT/AVG? | No | Sí |
SELECT UBICACION, COUNT(*) AS cant
FROM mascotas
GROUP BY UBICACION
HAVING COUNT(*) > 2; -- solo grupos con más de 25. El orden lógico de una consulta
Cuando aparecen todas las cláusulas juntas, este es el orden en que se escriben (y en que la base las procesa).
SELECT CARGO, COUNT(*) AS cantidad, ROUND(AVG(SALARIO),2) AS promedio
FROM empleados
WHERE SALARIO >= 1300 -- 1) filtra filas
GROUP BY CARGO -- 2) forma los grupos
HAVING AVG(SALARIO) > 1350 -- 3) filtra grupos
ORDER BY promedio DESC; -- 4) ordenaRegla de oro
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT.6. Con IA
Pedile a la IA
- «Traducí esta pregunta gerencial a SQL: ¿cuál es el salario promedio por cargo?»
- «Explicá la diferencia entre WHERE y HAVING con un ejemplo.»
- «¿Por qué da error si selecciono NOMBRE pero agrupo solo por CARGO?»
Ejercicios de práctica (8)
- Contá cuántas mascotas hay en total.
- Calculá el salario promedio, mínimo y máximo de todos los empleados.
- Contá cuántas mascotas hay por sexo (M/H).
- Mostrá el salario promedio por cargo.
- Mostrá cuántas mascotas hay por ubicación, ordenadas de mayor a menor.
- Con HAVING, mostrá solo las especies con 5 o más ejemplares.
- Contá cuántos alumnos hay inscriptos por curso (tabla alumnos_cursos).
- Por cargo, mostrá cuántos empleados ganan 1.300 o más y su promedio, dejando solo los cargos con promedio mayor a 1.350.
Bibliografía
- MySQL 8.0 Reference Manual. Aggregate Function Descriptions.
- MySQL 8.0 Reference Manual. MySQL Handling of GROUP BY.
- MySQL 8.0 Reference Manual. GROUP BY Modifiers (WITH ROLLUP).
- MySQL 8.0 Reference Manual. SELECT Statement.
El manual oficial de MySQL está en inglés; podés usar el traductor del navegador.
