Lecciones del módulo (4/4)
Filtrar grupos: HAVING
Una vez que tengas un resultado por grupo (lección anterior), a menudo querrás
mantener sólo los grupos que cumplan una condición: departamentos con más
de 2 personas, proyectos con un presupuesto promedio superior a 100k, usuarios con
al menos 10 pedidos. Para hacer esto WHERE no es suficiente.
¿Por qué DÓNDE no es suficiente?
WHERE filtra las filas de la tabla, antes de la agregación. entonces no puede ver
el resultado de COUNT(*) o AVG(...): cuando se ejecuta WHERE, esos
Los valores aún no se han calculado.
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;Para filtrar después de la agregación, hay una cláusula dedicada: HAVING.
La sintaxis
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING es para GROUP BY lo que WHERE es para FROM: la misma idea
("filtro"), pero se aplica después de la agrupación, en conjunto.
El orden lógico de las cláusulas.
Para no volver a confundir WHERE y HAVING, recuerde el orden en el que
SQL los ejecuta mentalmente:
FROM/JOIN: crea la tabla inicial uniendo fuentes.WHERE: elimina las filas que no te interesan.GROUP BY: reúne las filas restantes en grupos.HAVING: elimina los grupos que no te interesan.SELECT: calcula las columnas finales (incluidos los agregados).ORDER BY/LIMIT: reordenar y cortar.
Notas importantes:
- en
WHEREsólo puedes usar columnas de tabla; - en
HAVINGpuedes usar agrupar columnas y agregados.
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;Pruébalo
Para cada departamento, muestre el nombre (departamentos.nombre) y el recuento de empleados, PERO solo para departamentos con al menos 2 empleados. Dos columnas, una fila por departamento calificado.
Mostrar pista
La condición 'al menos 2' se convierte en COUNT(*) >= 2 en HAVING.
Solución disponible después de 3 intentos
Ejercicio de revisión
Muestre los departamentos (departamentos.nombre) cuyo salario promedio supera los 35000. Considere solo los empleados contratados a partir de 2018. Dos columnas: nombre y promedio. Ordenar por promedio descendente.
Mostrar pista
DONDE filtra las filas (empleados contratados a partir de 2018), HAVING filtra los grupos (promedio > 35000).
Solución disponible después de 3 intentos