Si ha estado escribiendo consultas SQL durante algún tiempo, probablemente esté bastante familiarizado con la cláusula WHERE. Si bien no tiene ningún efecto sobre los campos agregados, existe una forma de filtrar registros según los valores agregados, y es mediante la cláusula HAVING. En este blog se le explicará cómo funciona y le brindará algunos ejemplos sobre su uso en consultas SELECT.
Agregación y la cláusula HAVING
La agregación se usa generalmente junto con una agrupación. En SQL, eso se logra mediante la cláusula GROUP BY. La agregación, junto con la agrupación, nos permite obtener información de alto nivel sobre nuestros datos. Por ejemplo, una empresa de comercio electrónico podría querer realizar un seguimiento de las ventas durante un período de tiempo determinado.
En muchos casos, es posible que no queramos aplicar la cláusula GROUP BY en todo el conjunto de datos. En esos casos, podemos emplear el comando GROUP BY juntamente con la cláusula condicional HAVING, de esta manera se filtran los resultados no deseados. De manera similar a la cláusula WHERE, HAVING especifica una o más condiciones de filtro para un grupo o una agregación. Por lo tanto, HAVING siempre se colocará después de las cláusulas WHERE y GROUP BY, pero antes de la cláusula ORDER BY (opcional):
SELECT column_list FROM table_name WHERE where_conditions GROUP BY column_list HAVING having_conditions ORDER BY order_expression
Algunos ejemplos prácticos
Para tener una mejor idea de cómo funciona HAVING, ejecutemos algunas consultas SELECT en la base de datos de muestra de Sakila (Sakila Sample Database)
Nuestra primera consulta enumera a los principales clientes que alquilan películas, ordenados en orden descendente, de modo que la persona con más alquileres aparece en la parte superior. Usaremos la cláusula HAVING para eliminar a los clientes con menos de tres alquileres con el fin de acortar un poco la lista:
SELECT c.customer_id, c.first_name, c.last_name, COUNT(r.rental_id) AS total_rentals FROM customer AS c LEFT JOIN rental AS r ON c.customer_id = r.customer_id GROUP BY c.customer_id HAVING total_rentals >= 3 ORDER BY total_rentals DESC;
A continuación se muestra la consulta y la primera página de resultados en Navicat Premium:

A juzgar por los números de alquilerque vemos, podríamos haber reducido la lista mucho más.
Filtrado de filas con WHERE y HAVING
Así como GROUP BY y ORDER BY se aplican en diferentes puntos del proceso de consulta, también lo hacen WHERE y HAVING. Por lo tanto, podemos incluir ambos para filtrar los resultados antes y después de la agrupación y la agregación. Por ejemplo, podemos agregar una cláusula WHERE para restringir los resultados a la primera mitad de un año determinado:
SELECT c.customer_id, c.first_name, c.last_name, COUNT(r.rental_id) AS total_rentals FROM customer AS c LEFT JOIN rental AS r ON c.customer_id = r.customer_id WHERE r.rental_date BETWEEN '2005-01-01' AND '2005-06-30' GROUP BY c.customer_id HAVING total_rentals >= 3 ORDER BY total_rentals DESC;
Una vez más, aquí está la consulta anterior y la primera página de resultados en Navicat Premium:

Combinación de múltiples condiciones
Así como la cláusula WHERE admite múltiples condiciones utilizando las palabras clave AND y OR, también lo hace HAVING. Por ejemplo, podemos encontrar clientes cuyos números de alquiler se encuentran dentro de un rango determinado modificando la cláusula HAVING a algo como lo siguiente:
HAVING total_rentals >= 3 AND total_rentals <= 10
Conclusión
En el blog de hoy hemos aprendido a filtrar campos agrupados y agregados utilizando la cláusula HAVING.
¿Está interesado en Navicat Premium? ¡Puede probarlo durante 14 días completamente gratis para su evaluación!