HAVING filtra grupos. Se escribe después de GROUP BY y permite quedarse solo con los grupos que cumplen una condición sobre una función agregada: los clientes con más de un pedido, los productos que suman más de 1.000 €, etc.

Sintaxis
SELECT columnas, funcionAgregada(columna)
FROM tabla
WHERE condicionSobreFilas
GROUP BY columnas
HAVING condicionSobreGrupos;

HAVING frente a WHERE

Las dos filtran, pero en momentos distintos de la consulta:

Cláusula Qué filtra Cuándo se aplica ¿Admite funciones agregadas?
WHERE Filas Antes de agrupar No
HAVING Grupos Después de agrupar Sí

Por eso esta consulta falla: cuando se evalúa el WHERE, todavía no existen los grupos y COUNT(*) no tiene sentido.

PostgreSQL en tu navegador · Ctrl+Enter para ejecutar · los cambios se deshacen al terminar
Las funciones agregadas no pueden aparecer en la cláusula WHERE. SQL Server lo indica con un mensaje parecido a: Un agregado no puede aparecer en la cláusula WHERE a menos que esté en una subconsulta contenida en una cláusula HAVING.

Ejemplo básico

La forma correcta de obtener los clientes con más de un pedido es mover la condición a HAVING:

PostgreSQL en tu navegador · Ctrl+Enter para ejecutar · los cambios se deshacen al terminar
idClientes pedidos
2 2
4 2

Solo María (idClientes = 2) y Luis (idClientes = 4) han hecho más de un pedido.

HAVING con SUM

Cualquier función agregada vale. Aquí, los clientes cuyo gasto total supera los 3.000 €, unidos a la tabla Clientes para ver su nombre:

PostgreSQL en tu navegador · Ctrl+Enter para ejecutar · los cambios se deshacen al terminar
nombre apellidos gastoTotal
Luis Sanchez García 4999,00
Ana Fernandez Montero 4304,25
María Lopez ruiz 3199,78

WHERE y HAVING en la misma consulta

Lo habitual es combinarlas: WHERE descarta filas antes de agrupar y HAVING descarta grupos después. Esta consulta cuenta, por descripción de producto, cuántos pedidos se hicieron a partir de julio de 2022, y se queda solo con las descripciones que tienen al menos dos:

PostgreSQL en tu navegador · Ctrl+Enter para ejecutar · los cambios se deshacen al terminar
descripcionProducto pedidos unidades
Altavoz Alexa 2 100

El orden en que el motor procesa una consulta ayuda a entenderlo:

  1. FROM y JOIN: qué tablas intervienen.
  2. WHERE: qué filas se quedan.
  3. GROUP BY: cómo se agrupan.
  4. HAVING: qué grupos se quedan.
  5. SELECT: qué columnas se devuelven.
  6. ORDER BY: en qué orden.
Si una condición no usa funciones agregadas, ponla en WHERE aunque también funcione en HAVING: el motor descarta las filas antes de agrupar y la consulta hace menos trabajo.

Errores frecuentes

  • Usar un alias del SELECT en el HAVING. HAVING pedidos > 1 funciona en algunos motores, como MySQL, pero no en SQL Server, porque HAVING se evalúa antes que el SELECT. Repite la expresión: HAVING COUNT(*) > 1.
  • Olvidar el GROUP BY. Sin él, toda la tabla es un único grupo y HAVING devuelve una fila o ninguna.
  • Filtrar por una columna que no está agrupada. En HAVING solo pueden aparecer columnas del GROUP BY o funciones agregadas.

Practica

Modifica los ejemplos de arriba para responder a estas preguntas:

  1. ¿Qué clientes han comprado más de 50 unidades en total? (Pista: SUM(numeroProductos).)
  2. ¿Qué descripciones de producto tienen un precio medio superior a 400 €?
  3. ¿Qué pasa si en el último ejemplo cambias >= 2 por >= 1?