Tema SQL
Filtro sobre agregados (HAVING)
Filtra grupos ya formados por GROUP BY usando condiciones sobre SUM, COUNT, AVG, etc. No sustituye a WHERE: cada uno opera en una fase distinta del procesamiento lógico.
Descripción
WHERE restringe filas antes de agrupar; HAVING restringe grupos después de calcular agregados. Por tanto HAVING puede referenciar COUNT(*), SUM(importe) o expresiones derivadas de agregados, mientras WHERE no puede usar esos resultados directamente. Úsalo para reglas del tipo «solo clientes con más de N pedidos» o «departamentos cuyo salario medio supera un umbral». En motores con optimizador avanzado, condiciones redundantes pueden fusionarse, pero mantén la semántica clara para quien lea la consulta.
Estructura general
Forma habitual de la sentencia: orden de cláusulas, qué parte filtra, agrupa o proyecta columnas, y qué devuelve el motor. Cópiala como plantilla y sustituye nombres por tus tablas reales.
SELECT columnas_agrupadas, AGREGADO(...)
FROM tabla
[ WHERE condición_por_fila ]
GROUP BY columnas_agrupadas
HAVING condición_sobre_agregados;
Componentes
Cada componente tiene un papel concreto en la ejecución lógica de la sentencia. Léelos en orden: así entiendes qué puedes omitir, qué es obligatorio y qué expresiones son válidas en cada sitio según tu motor.
- WHERE
- Se evalúa sobre cada fila de la tabla (o join) antes de agrupar. Reduce el volumen de datos que entra en el GROUP BY y mejora el rendimiento cuando está soportado por índices.
- GROUP BY
- Define una fila de salida por cada combinación única de las columnas listadas. Todas las filas del grupo comparten esos valores de agrupación.
- HAVING
- Condición booleana sobre el grupo: comparaciones entre agregados, con constantes o entre sí. Es el lugar correcto para umbrales sobre COUNT/SUM/AVG tras agrupar.
Ejemplos
Ejemplo 1
SELECT usuario_id, COUNT(*) AS num_pedidos
FROM pedidos
GROUP BY usuario_id
HAVING COUNT(*) >= 3;
Ejemplo 2
SELECT region, SUM(ventas) AS t
FROM tiendas
GROUP BY region
HAVING SUM(ventas) > 1000;
Temas relacionados
Enlaces internos para seguir leyendo: SELECT, WHERE, JOIN, GROUP BY y el resto de la referencia SQL.
Los ejemplos son ilustrativos. En producción usa consultas parametrizadas (prepared statements), revisa índices y aplica el principio de menor privilegio en cuentas de base de datos.