Saber cuándo filtrar filas y cuándo filtrar grupos es una de las diferencias más importantes a la hora de escribir consultas SQL eficientes. HAVING es la cláusula que permite aplicar condiciones sobre los resultados de una agrupación, y confundirla con WHERE no solo produce resultados incorrectos, sino que puede afectar significativamente el rendimiento en tablas grandes.
¿Cuál es la diferencia entre WHERE y HAVING en SQL?
Aunque ambas cláusulas sirven para filtrar, actúan en momentos distintos del proceso de ejecución de una query [0:15]:
- WHERE filtra filas antes de agrupar.
- HAVING filtra grupos después de agrupar.
Son dos filtros que operan en etapas diferentes, y la gran ventaja es que podemos usar ambos dentro de la misma consulta. Primero WHERE reduce las filas que entran a la agrupación, y luego HAVING descarta los grupos que no cumplen la condición deseada.
¿Cómo funciona HAVING con una agrupación simple?
Para ilustrarlo, se parte de la tabla productos en la base de datos Tienda Latam. El objetivo es encontrar las categorías con más de cinco productos [1:22].
Primero se ejecuta la agrupación sin HAVING:
sql SELECT categoriaID, COUNT(*) AS cantidad_productos FROM productos GROUP BY categoriaID;
Este resultado devuelve ocho filas mostrando cuántos productos tiene cada categoría: cinco, cuatro, seis, tres, ocho, entre otros valores. Hasta aquí solo hay una función de agregación (COUNT) combinada con GROUP BY.
Ahora se aplica el filtro posterior con HAVING [2:25]:
sql SELECT categoriaID, COUNT() AS cantidad_productos FROM productos GROUP BY categoriaID HAVING COUNT() > 5;
El resultado se reduce a solo dos categorías (categoría 1 y categoría 2), que son las únicas con más de cinco elementos. Si se necesita incluir las que tienen exactamente cinco, basta con cambiar el operador a >=:
sql HAVING COUNT(*) >= 5;
Con ese ajuste, el resultado pasa a cuatro categorías. El operador mayor estricto (>) excluye el valor indicado, mientras que mayor o igual (>=) lo incluye.
¿Cómo combinar WHERE y HAVING en una misma consulta?
El verdadero poder aparece cuando se necesitan ambos filtros. El ejemplo trabaja con la tabla pedidos y busca los clientes que realizaron más de tres pedidos durante el año 2024 [3:20].
La construcción paso a paso es la siguiente:
sql SELECT clienteID, COUNT() AS pedidos_2024 FROM pedidos WHERE EXTRACT(YEAR FROM fecha_pedido) = 2024 GROUP BY clienteID HAVING COUNT() > 3 ORDER BY pedidos_2024 DESC;
¿Qué hace cada parte de la query?
- WHERE con
EXTRACT: aplica una función de tiempo que extrae el año de la columna fecha_pedido y filtra solo las filas del año 2024. Este es el primer filtro, que actúa antes de la agrupación [3:50].
- GROUP BY: agrupa las filas restantes por
clienteID.
- HAVING: es el segundo filtro, que descarta todos los grupos cuyo conteo sea tres o menos. Mayor estricto que tres significa de cuatro hacia arriba [4:30].
- ORDER BY DESC: ordena el resultado de forma descendente para generar un ranking.
Al ejecutar la consulta completa, el resultado muestra únicamente al cliente 100 y al cliente 81, que son los únicos que superaron tres pedidos en 2024.
¿Cuál es el orden correcto de las cláusulas en SQL?
La secuencia lógica que se debe respetar es:
SELECT con las columnas y funciones de agregación.
FROM indicando la tabla de origen.
WHERE para filtrar filas individuales.
GROUP BY para agrupar lo que no es agregación.
HAVING para filtrar los grupos resultantes.
ORDER BY para ordenar la salida final.
Respetar este orden garantiza que cada filtro actúe en el momento correcto y que los resultados sean precisos.
Pon a prueba lo aprendido con estos tres ejercicios sobre Tienda Latam: categorías con más de diez productos, países con más de cien clientes y clientes con más de tres pedidos. Comparte tus resultados en los comentarios.