Filtros y agregación · orden lógico

WHERE vs HAVING

WHERE decide qué filas llegan al agrupamiento; HAVING decide qué grupos permanecen después de calcularlos.

Lectura: 5–7 minComparación paso a pasoIncluye práctica guiada
Contenido de esta guía

Respuesta rápida

WHERE filtra filas antes de GROUP BY. HAVING filtra grupos después de calcular agregaciones.

Una consulta puede usar las dos cláusulas cuando necesita limitar primero los datos de entrada y después conservar solo los grupos que cumplen un resumen.

Piensa en dos preguntas diferentes

  • WHERE: ¿qué filas individuales participan?
  • HAVING: ¿qué grupos calculados permanecen?

Esta distinción es más fiable que memorizar qué palabras “van” con cada cláusula. Identifica primero si la condición puede evaluarse sobre una fila o necesita conocer un total, una media, un máximo u otra agregación.

Comparación entre WHERE y HAVING
AspectoWHEREHAVING
Unidad que filtraFilasGrupos
Momento lógicoAntes de agruparDespués de agrupar
Condición típicaactivo = 1COUNT(*) >= 2
EfectoCambia las filas que alimentan el cálculoOculta grupos ya calculados

Ejemplo paso a paso

SQL
SELECT ciudad,
       COUNT(*) AS clientes_activos
FROM clientes
WHERE activo = 1
GROUP BY ciudad
HAVING COUNT(*) >= 2
ORDER BY clientes_activos DESC, ciudad;
  1. WHERE activo = 1 retira las filas inactivas.
  2. GROUP BY ciudad reúne las filas restantes por ciudad.
  3. COUNT(*) calcula cuántos clientes activos tiene cada grupo.
  4. HAVING COUNT(*) >= 2 conserva solo ciudades con dos o más.
Resultado esperado
ciudadclientes_activos
Madrid3
Bilbao2
Sevilla2
Valencia2

Cómo decidir cláusula por cláusula

  1. Escribe la condición en lenguaje natural.
  2. Pregunta si puede resolverse mirando una sola fila.
  3. Si la respuesta es sí, empieza por WHERE.
  4. Si necesita un cálculo del grupo, utiliza HAVING.
  5. Cuando existan ambas necesidades, aplica primero WHERE y después HAVING.

Errores frecuentes

Intentar usar una agregación en WHERE

Incorrecto
SELECT ciudad, COUNT(*)
FROM clientes
WHERE COUNT(*) >= 2
GROUP BY ciudad;

COUNT(*) todavía no existe en el momento lógico de WHERE. Esa condición pertenece a HAVING.

Usar HAVING para una condición de fila

Algunos motores aceptan extensiones, pero filtrar antes con WHERE expresa mejor la intención y evita agrupar filas que no deberían participar.

Olvidar que WHERE cambia el cálculo

Excluir pedidos cancelados antes de sumar produce un total distinto de sumar todos los pedidos y filtrar grupos después.

Práctica guiada

Intermedia · agregación

Clientes activos por ciudad

Devuelve las ciudades con al menos dos clientes activos. Muestra la ciudad y el conteo, ordenando primero por el conteo descendente y después por ciudad.

Compatibilidad y extensiones

La separación conceptual entre filtros de fila y de grupo es portable. Algunos motores permiten que HAVING haga referencia a alias o se use en situaciones adicionales. Para una ruta inicial clara, escribe las condiciones de fila en WHERE y reserva HAVING para condiciones que dependen del grupo.

Qué debes recordar

  • WHERE reduce las filas antes de agrupar.
  • HAVING reduce grupos después de agregar.
  • Una consulta puede y suele necesitar ambas.
  • Colocar un filtro en otra fase puede cambiar el resultado.

Conceptos relacionados

Fuentes técnicas consultadas

Para situar ambos filtros en la consulta completa, consulta el orden de ejecución de SQL paso a paso.