Volver a la lista de artículos Artículos
Lectura de 6 minutos

Explicación de la cláusula HAVING en SQL

¿Qué es la cláusula HAVING de SQL? ¿Por qué se necesita y dónde se utiliza? Vamos a explicar HAVING en detalle.

HAVING es una cláusula muy común en las consultas SQL. Al igual que WHERE, ayuda a filtrar los datos; sin embargo, HAVING funciona de manera diferente. Si está familiarizado con la cláusula GROUP BY y sólo ha oído hablar de HAVING - o si no está familiarizado con HAVING en absoluto - este artículo es lo que necesita. Siga leyendo y amplíe sus conocimientos sobre HAVING en SQL.

¿Qué es la cláusula HAVING en SQL?

En SQL, la cláusula HAVING:

  • Filtra datos basados en criterios definidos.
  • Es comúnmente usada en la creación de reportes.
  • Sólo se utiliza en SELECT.
  • Trabaja con GROUP BY.

Si conoce la cláusula GROUP BY, sabrá que se utiliza para agregar valores: pone los registros en grupos para calcular los valores de agregación (estadísticas) para ellos. HAVING filtra los registros según estos valores de agregación. Lo discutiremos a fondo aquí, pero encontrarás más detalles en nuestro curso interactivo SQL para principiantes.

Si necesitas un repaso de GROUP BY, te recomiendo los artículos Getting the Hang of the GROUP BY Clause de Marian Dziubak y Grouping Data in SQL Server de Belma Mesihovic.

Sintaxis HAVING

Antes de comenzar con un ejemplo, veamos la sintaxis de la cláusula HAVING. HAVING se coloca siempre después de las cláusulas WHERE y GROUP BY pero antes de la cláusula ORDER BY. Fíjese bien:

SELECT column_list 
FROM table_name
WHERE where_conditions
GROUP BY column_list
HAVING having_conditions
ORDER BY order_expression

La cláusula HAVING especifica la condición o condiciones para un grupo o una agregación.

La tabla employee tabla de abajo nos ayuda a analizar la cláusula HAVING. Contiene los IDs de los empleados (la columna emp_id ), el department donde trabaja ese empleado, y el salary del empleado.

employee_iddepartmentsalary
1HR23000
2HR28000
3Finance35000
4Marketing15000
5Marketing25000
6Finance56000
7Finance41000

Para calcular la suma de los salarios de cada departamento, escribiría esta consulta:

SELECT department, SUM(salary)
FROM employee
GROUP BY department;

Este es el resultado:

departmentsalary
HR51000
Marketing40000
Finance132000

Ahora, supongamos que necesita mostrar los departamentos en los que la suma de los salarios es de 50.000 dólares o más. En este caso, debe utilizar una cláusula HAVING:

SELECT department, SUM(salary)
FROM employee
GROUP BY department
HAVING SUM(salary) >= 50000;

Y el resultado es:

departmentsalary
HR51000
Finance132000

Como ve, el conjunto de resultados contiene sólo la suma de los salarios de los departamentos de RRHH y Finanzas. Esto se debe a que la suma de los salarios de Marketing es inferior a 50.000 dólares.

Esta consulta primero agrupa los registros según los departamentos y calcula los valores agregados, en este caso, la suma de todos los salarios. En el siguiente paso, se comprueba la condición en HAVING: comparamos el valor devuelto por SUM(salary) para un departamento determinado con 50.000 dólares. Si este valor es igual o superior a 50.000 dólares, se devuelve el registro. En nuestro ejemplo, se muestra la suma de los salarios de los departamentos de RRHH (51.000$) y Finanzas (132.000$).

Filtrado de filas mediante WHERE y HAVING

A continuación, vamos a ver cómo filtrar filas a nivel de registro y a nivel de grupo en la misma consulta. En primer lugar, observe los datos de la tabla del informe sale:

salesman_idsale_monthtotal_value
1January34000
1February14000
1March22000
1April2000
2January20000
2February0
2March17000
2April0
3March1000
3April35000

La siguiente consulta selecciona la suma de todas las ventas de cada vendedor cuyo valor medio de venta es superior a 20.000 dólares. (Nota: El vendedor con ID=3 no está incluido, ya que sólo empezó a trabajar en marzo).

SELECT salesman_id, SUM(total_value)  
FROM sale 
WHERE salesman_id != 3
GROUP BY salesman_id 
HAVING SUM(total_value) > 40000;

Este es el resultado:

salesman_idsum
172000

Esta consulta primero filtra los registros, utilizando la cláusula WHERE para seleccionar los registros con ID de vendedor distinto de 3 (WHERE salesman_id != 3). A continuación, calcula la suma de las ventas totales de los representantes de ventas con los ID 1 y 2. Lo hace agrupando individualmente los registros de ambos representantes (GROUP BY salesman_id). Al final, la consulta filtra los registros utilizando HAVING para comprobar si el valor agregado (suma de las ventas totales) es superior a 40.000 dólares (HAVING SUM(total_value) > 40000).

Filtración de filas en base a múltiples valores utilizando HAVING

La cláusula HAVING también permite filtrar filas utilizando más de un valor agregado (es decir, valores de diferentes funciones agregadas). Observe la siguiente consulta:

SELECT salesman_id, SUM(total_value) 
FROM sale 
WHERE salesman_id != 3
GROUP BY salesman_id 
HAVING SUM(total_value) > 36000 AND AVG(total_value) > 15000;

El resultado:

salesman_idsum
172000

Esta consulta devuelve los ID de los vendedores que 1) tienen un total de ventas superior a 36.000 dólares y 2) tienen un promedio de ventas superior a 15.000 dólares cada mes. Sólo el representante de ventas con ID=1 cumple las dos condiciones. Observe que no seleccionamos el promedio de las ventas totales de cada vendedor, sino sólo la suma de todas sus ventas; el promedio está sólo en la condición HAVING.

La diferencia entre HAVING y WHERE

El ejemplo de la última sección mostraba cómo filtrar registros tanto con WHERE como con HAVING. Ahora consideraremos la diferencia entre estas dos cláusulas.

La diferencia básica es que WHERE trabaja sobre registros individuales y HAVING trabaja sobre registros agrupados (después de procesar el GROUP BY). HAVING se utiliza sólo en las sentencias SELECT, pero WHERE puede utilizarse en otras sentencias, como DELETE o UPDATE.

HAVING y WHERE filtran los datos en momentos diferentes. WHERE se procesa antes que GROUP BY. Esto significa que primero se seleccionan los registros y luego se filtran con WHERE. Es un filtrado a nivel de registro. Después, los registros resultantes se agrupan y se calcula el valor agregado.

HAVING filtra los registros a nivel de grupo - después de WHERE y GROUP BY. HAVING comprueba si el valor agregado de un grupo cumple su(s) condición(es). Debe utilizar una función de agregación para filtrar registros sólo en HAVING; WHERE no puede incluir una función de agregación.

Puedes leer más sobre la diferencia entre WHERE y HAVING en HAVING vs. WHERE en SQL: What You Should Know por Ignacio L. Bisso.

HAVING: Una cláusula muy útil

HAVING es muy útil en las consultas SQL. Filtra los datos después de que las filas son agrupadas y los valores son agregados - algo que se hace a menudo en los informes.

Espero que este artículo te haya ayudado a entender la cláusula HAVING. Quizás incluso te mueva a ampliar tus conocimientos de SQL. Si estás interesado en aprender más sobre SQL, prueba nuestro curso interactivo SQL para principiantes curso sobre la LearnSQL.es plataforma.