Agregación · filtros de grupos

HAVING

HAVING decide qué grupos permanecen después de calcular agregaciones. WHERE, en cambio, decide qué filas llegan a formar esos grupos.

Lectura: 5–7 minEjemplo comprobadoPráctica con pistas
Contenido de esta guía

Qué hace HAVING

HAVING filtra los grupos producidos por una consulta agregada. Se utiliza normalmente después de GROUP BY y permite expresar condiciones sobre resultados como COUNT(*), SUM(total) o AVG(precio).

La pregunta clave es: ¿la condición habla de una fila individual o de un grupo ya resumido? Si habla de filas, suele pertenecer a WHERE. Si habla del resumen, pertenece a HAVING.

Orden lógico de las dos condiciones

  1. FROM obtiene las filas de origen.
  2. WHERE descarta filas antes de agrupar.
  3. GROUP BY forma grupos.
  4. Las funciones agregadas calculan un resultado por grupo.
  5. HAVING conserva solo los grupos que cumplen su condición.
  6. SELECT presenta las columnas del resultado y ORDER BY las ordena.

Filtrar antes puede cambiar el agregado. No muevas una condición de WHERE a HAVING solo porque la consulta «también funciona».

Ejemplo guiado: clientes con compras superiores a 300

Primero se excluyen pedidos cancelados. Después se agrupan los pedidos restantes por cliente y se conservan los totales mayores de 300.

SQL
SELECT c.nombre,
       ROUND(SUM(p.total), 2) AS total_comprado,
       COUNT(*) AS pedidos
FROM clientes AS c
JOIN pedidos AS p
  ON p.cliente_id = c.id
WHERE p.estado <> 'cancelado'
GROUP BY c.id, c.nombre
HAVING SUM(p.total) > 300
ORDER BY total_comprado DESC, c.nombre;
Resultado comprobado
nombretotal_compradopedidos
Sara Gómez1112,02
Ana Torres377,42

WHERE evita que los importes cancelados entren en la suma. HAVING evalúa el total de cada cliente una vez calculado.

HAVING sin GROUP BY

Algunos usos agregan toda la entrada como un único grupo. Por ejemplo, una consulta puede devolver una alerta solo cuando el total de filas supera un umbral. Aunque el motor lo permita, utiliza esta forma únicamente cuando la intención de «un único grupo global» sea clara.

Errores frecuentes

Usar WHERE con una función agregada

WHERE COUNT(*) > 3 intenta evaluar el conteo antes de que existan los grupos. La condición agregada debe ir en HAVING.

Filtrar filas tarde

Si solo quieres sumar pedidos enviados, coloca estado = 'enviado' en WHERE. Agrupar todo y tratar de corregirlo después puede producir otro resultado.

Depender de un alias en HAVING

La posibilidad de usar un alias de SELECT en HAVING cambia entre motores. Para una consulta portable, repite la expresión agregada.

Práctica guiada

Intermedia · agregación

Estados con al menos cuatro pedidos

Agrupa los pedidos por estado. Muestra el estado, el número de pedidos y la suma del importe. Conserva solo grupos con cuatro pedidos o más y ordena por el conteo descendente y el estado.

Compatibilidad entre motores

La combinación GROUP BY ... HAVING es común. Las reglas para seleccionar columnas no agrupadas y reutilizar alias varían. Mantén la consulta explícita: agrupa todas las columnas descriptivas necesarias y escribe la expresión agregada completa en HAVING.

Qué debes recordar

  • WHERE filtra filas antes de agrupar.
  • HAVING filtra grupos después de agregar.
  • Las condiciones sobre COUNT, SUM o AVG suelen ir en HAVING.
  • El lugar del filtro puede cambiar el resultado, no solo la sintaxis.

Conceptos relacionados

Fuentes técnicas consultadas