- Paso 1. Agrupar los datos
- Paso 2. Filtrar después de agrupar
- La palabra clave HAVING
- Paso 3. Comparar WHERE y HAVING
Hasta ahora ya sabes agrupar datos y calcular resultados por usuario con GROUP BY. Pero a veces queremos ir un paso más allá: filtrar esos grupos según los resultados agregados.
Por ejemplo, imagina que queremos ver cuánto tiempo ha pasado cada estudiante en la plataforma de Códica.
Paso 1. Agrupar los datos
SELECT
user_id,
SUM(spent_minutes)
FROM course_reviews
GROUP BY user_id
ORDER BY user_id;
Mira en DB Fiddle
Cada fila muestra el tiempo total que un usuario ha pasado en los cursos.
Ahora observamos algo interesante: algunos usuarios apenas han estado unos minutos. Podríamos querer centrarnos en esos —por ejemplo, para entender por qué abandonaron pronto.
Paso 2. Filtrar después de agrupar
Queremos quedarnos solo con los usuarios que pasaron menos de 30 minutos en total. Podríamos pensar en usar WHERE, pero… eso no funcionará.
🤔 ¿Por qué? Porque WHERE se aplica antes de agrupar, y en este momento todavía no existen los valores de SUM(spent_minutes).
Para filtrar después de agrupar, usamos otra palabra clave: HAVING.
La palabra clave HAVING
SELECT
user_id,
SUM(spent_minutes)
FROM course_reviews
GROUP BY user_id
HAVING SUM(spent_minutes) < 30
ORDER BY user_id;
| user_id | sum |
|---|---|
| 3 | 9 |
| 16 | 27 |
| 23 | 4 |
| 67 | 27 |
| 75 | 27 |
| 78 | 13 |
Mira en DB Fiddle
💡 Esta consulta agrupa primero y filtra después. Solo se muestran los usuarios cuyo total de minutos (SUM) es menor que 30.
En otras palabras: HAVING actúa como un WHERE, pero sobre el resultado agrupado.
Paso 3. Comparar WHERE y HAVING
Ahora queremos buscar solo entre los primeros 40 usuarios. Para eso, podemos agregar una condición adicional:
SELECT
user_id,
SUM(spent_minutes)
FROM course_reviews
WHERE user_id <= 40
GROUP BY user_id
HAVING SUM(spent_minutes) < 30
ORDER BY user_id;
| user_id | sum |
|---|---|
| 3 | 9 |
| 16 | 27 |
| 23 | 4 |
Mira en DB Fiddle
Aquí ocurre algo importante:
- Primero,
WHEREelimina todas las filas dondeuser_id > 40. - Después, el sistema agrupa los datos por usuario.
- Finalmente,
HAVINGfiltra los grupos cuyo total sea menor que 30.
Cuando sea posible, usa WHERE para filtrar antes de agrupar, y deja HAVING solo para las condiciones sobre funciones agregadas.
Resumen
WHEREfiltra filas antes de agrupar.HAVINGfiltra después de agrupar, y se usa con funciones agregadas comoSUM()oCOUNT().- El orden general de la consulta es:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY - Combinar ambos te permite construir consultas potentes y precisas.
Materiales adicionales
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.