CodeGym /Cursos /SQL SELF /Filtrado de datos agregados con HAVING

Filtrado de datos agregados con HAVING

SQL SELF
Nivel 8 , Lección 1
Disponible

Hay algo que todavía no hemos comentado, y es ¿cómo filtrar los grupos después de aplicar agregados? A veces no necesitamos todas las facultades — solo las que tienen más de cien estudiantes. O queremos ver solo los departamentos donde el salario medio es mayor de 50.000. Hoy vamos a conocer el filtrado de datos agregados usando HAVING.

¿Para qué necesitamos HAVING si ya tenemos WHERE? ¿No podríamos poner WHERE después de GROUP BY? :)

¡No es tan simple! Primero, el orden de los operadores en SQL está fijado y WHERE se ejecuta antes que GROUP BY.

¿Y si intentamos ponerlo después de GROUP BY?

Tampoco se puede. Muy a menudo necesitamos filtrar filas de la tabla antes de agrupar. Luego hacemos la agrupación sobre los datos filtrados. Y después descartamos algunos datos innecesarios tras la agrupación.

Entonces, ¿por qué no tomar el operador WHERE, copiarlo, llamarlo HAVING y ponerlo después de GROUP BY?

¡Pues sí, eso es justo lo que hacemos! :)

Diferencia entre HAVING y WHERE

WHERE filtra filas antes de la agrupación.

Imagina que seleccionas tartas por sabor: las de fresa y chocolate las dejas, el resto fuera. Eso es tarea de WHERE.

HAVING filtra después de que los datos han sido agrupados y las funciones agregadas han hecho su magia.

Por ejemplo, ya agrupaste las tartas por mesa, contaste cuántas hay y ahora quieres dejar solo las mesas donde hay más de tres tartas.

Así que HAVING se usa para filtrar datos a nivel de grupo.

Sintaxis de HAVING

La sintaxis es casi igual que la de WHERE, pero funciona un poco diferente:

SELECT columnas, funciones_agregadas
FROM tabla
GROUP BY columnas
HAVING condición;

Etapas de ejecución:

  1. Primero las filas se filtran con WHERE.
  2. Luego los datos se agrupan usando GROUP BY.
  3. Se aplican funciones agregadas a los resultados de la agrupación.
  4. Finalmente, el resultado se filtra usando HAVING.

Ejemplos de uso de HAVING

Ejemplo 1: Filtrar facultades con muchos estudiantes

Quieres saber qué facultades en la universidad tienen más de 100 estudiantes. Supón que tenemos la tabla students:

id name faculty
1 Alice Engineering
2 Bob Engineering
3 Charlie Arts
4 Daisy Business
5 ... ...

Consulta:

SELECT faculty, COUNT(*) AS student_count
FROM students
GROUP BY faculty
HAVING COUNT(*) > 100;

¿Qué pasa aquí?

  • Primero agrupamos los estudiantes por la columna faculty usando GROUP BY.
  • Luego la función agregada COUNT(*) cuenta cuántos estudiantes hay en cada facultad.
  • Por último, HAVING descarta todas las facultades donde hay 100 estudiantes o menos.

Resultado:

faculty student_count
Engineering 150
Arts 120

Ejemplo 2: Departamentos con salario medio alto

Quieres encontrar solo los departamentos donde el salario medio de los empleados supera los 50.000. Supón que tenemos la tabla employees:

id name department salary
1 Alice IT 60000
2 Bob HR 45000
3 Charlie IT 70000
4 Daisy HR 52000
5 ... ... ...

Consulta:

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

Resultado:

department avg_salary
IT 65000

Ojo: HAVING trabaja con los resultados que se han calculado después de GROUP BY.

Orden de ejecución de WHERE, GROUP BY y HAVING

El filtrado con WHERE y HAVING ocurre en diferentes etapas. Para entender mejor la diferencia, vamos a ver el proceso paso a paso de una consulta:

  1. WHERE: filtrado de filas.

    En esta etapa se procesan todas las filas de la tabla. Si una fila no cumple la condición de WHERE, ni siquiera pasa a la siguiente fase.

  2. GROUP BY: agrupación de filas.

    Después del filtrado, las filas se agrupan según las columnas indicadas en GROUP BY.

  3. Funciones agregadas:

    Se aplican funciones agregadas como COUNT(), AVG(), SUM(), etc. a los datos agrupados.

  4. HAVING: filtrado de grupos.

    En esta etapa solo se procesan los resultados de los agregados. Las condiciones de HAVING se aplican solo a los grupos.

Particularidades de HAVING

Particularidad 1: Trabajar con agregados

La diferencia principal de HAVING respecto a WHERE es que trabaja con funciones agregadas. Por ejemplo:

SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

En esta consulta AVG(salary) no se puede usar dentro de WHERE, porque WHERE procesa filas antes de la agrupación. Una consulta como:

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

provocará un error: aggregate functions are not allowed in WHERE.

Particularidad 2: Filtrar sin agrupación

Puedes usar HAVING incluso sin un GROUP BY explícito. En ese caso la consulta se interpreta como si hubiera un solo grupo — todos los registros:

SELECT AVG(salary) AS avg_salary
FROM employees
HAVING AVG(salary) > 50000;

Ejemplo práctico

Supón que tenemos una tienda y una tabla de ventas sales:

id product_id sales_amount
1 101 200.00
2 102 300.00
3 101 400.00
4 103 150.00

Consulta: encontrar productos con un volumen total de ventas mayor de 500.

SELECT product_id, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 500;

Resultado:

product_id total_sales
101 600.00

Errores típicos

Uso de agregados en WHERE:

Por ejemplo:

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

Error: no se pueden usar funciones agregadas en WHERE.

Errores con NULL:

Si los datos contienen NULL, el filtrado puede dar resultados inesperados. Por ejemplo:

SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) > 0;

Si la columna salary solo contiene NULL, el resultado puede ser cero o vacío.

¡Enhorabuena! A este nivel ya puedes filtrar datos agregados con confianza. Recuerda que HAVING es tu llave para el análisis a nivel de grupos, donde WHERE ya no es suficiente.

2
Tarea
SQL SELF, nivel 8, lección 1
Bloqueada
Filtrado de estudiantes por facultades con más de dos estudiantes
Filtrado de estudiantes por facultades con más de dos estudiantes
2
Tarea
SQL SELF, nivel 8, lección 1
Bloqueada
Filtrado de productos por el total de ventas
Filtrado de productos por el total de ventas
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION