Error SQL · WHERE, HAVING y agregaciones

Función de agregación en WHERE: filtra filas antes y grupos después

Si intentas usar COUNT, SUM o AVG directamente en WHERE, estás mezclando dos etapas distintas de la consulta. Decide si la condición filtra filas de entrada o grupos ya calculados.

Lectura: 13–17 minEjemplo reproduciblePráctica con pistas

El síntoma: WHERE intenta usar un valor que todavía no se ha agregado

Las funciones COUNT, SUM, AVG, MIN y MAX resumen varias filas. WHERE, en cambio, decide qué filas participan antes de formar grupos y calcular los agregados. Por eso una condición como WHERE COUNT(*) > 2 no expresa una etapa válida en la consulta habitual.

PostgreSQL documenta esta diferencia de forma directa: WHERE selecciona filas antes de calcular grupos y agregados, mientras que HAVING selecciona grupos después de ese cálculo.

Ejemplo reproducible: contar categorías dentro de WHERE

SQL problemático
WITH ventas(categoria, importe) AS (
  VALUES ('A', 10), ('A', 20), ('A', 30),
         ('B', 5),  ('B', 7)
)
SELECT categoria, COUNT(*) AS ventas
FROM ventas
WHERE COUNT(*) >= 3
GROUP BY categoria;

La condición depende de COUNT(*), que solo existe después de agrupar. El problema no se resuelve moviendo palabras al azar: primero identifica si estás filtrando filas o grupos.

Usa HAVING cuando la condición depende del resultado agregado

SQL corregido
WITH ventas(categoria, importe) AS (
  VALUES ('A', 10), ('A', 20), ('A', 30),
         ('B', 5),  ('B', 7)
)
SELECT categoria,
       COUNT(*) AS ventas,
       SUM(importe) AS total
FROM ventas
GROUP BY categoria
HAVING COUNT(*) >= 3;
Resultado: solo permanece el grupo con al menos tres ventas
categoriaventastotal
A360

WHERE y HAVING pueden aparecer juntos

No son alternativas exclusivas. Usa WHERE para decidir qué filas entran al cálculo y HAVING para decidir qué grupos permanecen después.

Dos etapas de filtrado
SELECT categoria, COUNT(*) AS ventas_validas
FROM ventas
WHERE importe >= 10
GROUP BY categoria
HAVING COUNT(*) >= 2;

Primero desaparecen las ventas de importe menor que 10. Después se forman los grupos con las filas restantes y solo se conservan los que alcanzan dos registros.

Método de diagnóstico

  1. Subraya la condición que provoca el error.
  2. Pregunta de qué depende: ¿de una columna de cada fila o de un agregado calculado sobre varias filas?
  3. Si depende de filas, usa WHERE.
  4. Si depende del grupo, usa HAVING y comprueba que el GROUP BY tenga la granularidad que realmente necesitas.

Error frecuente: mover todo a HAVING

Que HAVING acepte una condición no significa que sea su mejor lugar

Una condición simple sobre filas, como importe >= 10, expresa mejor su intención en WHERE. Filtrar antes también evita que filas irrelevantes participen en la agrupación. Reserva HAVING para condiciones que realmente dependen del grupo o del agregado.

Práctica correctiva

Básica · agregaciones

Separa el filtro de filas del filtro de grupos

Quieres contar únicamente ventas de al menos 10 euros y mostrar solo categorías que tengan dos o más de esas ventas. ¿Dónde va cada condición?

Qué debes recordar

  • WHERE filtra filas antes de agrupar.
  • HAVING filtra grupos después de calcular agregados.
  • Una condición puede necesitar ambas etapas en la misma consulta.
  • No muevas filtros de fila a HAVING solo para evitar un mensaje de error.

Conceptos relacionados

Fuentes técnicas consultadas