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

HAVING vs. WHERE en SQL: Lo que debe saber

Este artículo trata sobre las cláusulas WHERE y HAVING de SQL. Ambas cláusulas forman parte de los fundamentos del comando SELECT de SQL. Tienen usos similares, pero también hay diferencias importantes que toda persona que utilice SQL debería conocer. Veamos qué hay detrás del debate HAVING vs. WHERE.

En este artículo, supondremos que trabajamos para una agencia social del gobierno que apoya a personas o familias cuyos ingresos están por debajo de un determinado umbral. Esta agencia utiliza varias métricas para identificar a las personas o familias que necesitan ayuda.

En primer lugar, vamos a ver el conjunto de datos de muestra. A continuación, en el resto del artículo, crearemos consultas basadas en este conjunto de datos.

Conjunto de datos de muestra

Este conjunto de datos describe a personas pertenecientes a cuatro familias que viven en dos ciudades. Para simplificar, supondremos que last_name identifica a la familia. La idea es obtener métricas a nivel de persona y a nivel de familia.

TABLE Persons

namelast_namebirth_dateyear_incomecity
MaryRoberts1964-01-1178000Oklahoma
PeterRoberts1962-09-2586500Oklahoma
JohnRoberts1999-06-030Oklahoma
SueRoberts1996-03-060Oklahoma
MelindaRoberts1998-04-040Oklahoma
GeorgeHudson1953-02-2348000Oklahoma
NancyHudson1958-12-0665000Oklahoma
AnnHudson1979-04-0235000Oklahoma
CarlGibson1963-04-03102800Phoenix
LiGibson1963-12-2796000Phoenix
KateBishop1994-07-10920000Phoenix
MarkBishop2018--9-130Phoenix

Bien. Ahora que hemos visto el conjunto de datos, ¡comencemos!

WHERE y HAVING: Ejemplos sencillos

En palabras sencillas, las cláusulas WHERE y HAVING actúan como filtros; eliminan del resultado final de una consulta los registros o datos que no cumplen ciertos criterios. Sin embargo, se aplican a conjuntos de datos diferentes. Este es el punto importante que hay que entender sobre WHERE vs. HAVING: WHERE filtra a nivel de registro, mientras que HAVING filtra a nivel de "grupo de registros".

Veamos algunos ejemplos.

He aquí una consulta de ejemplo que utiliza la cláusula WHERE: Supongamos que queremos obtener los nombres de las personas con ingresos anuales superiores a 100.000 dólares. Necesitamos filtrar (o descartar) a nivel de registro, por lo que utilizaremos la cláusula WHERE en lugar de la cláusula HAVING para esta consulta:

Texto de la consulta para copiar y pegar:

SELECT name, last_name
FROM  persons
WHERE year_income > 100000;

WHERE vs HAVING

Ahora vamos a intentar una consulta similar, pero esta vez con la cláusula HAVING: Supongamos que queremos obtener la last_name de las familias que tienen unos ingresos familiares (es decir, la suma de los ingresos de todos los miembros de la familia) superiores a 100.000 dólares. Este es un caso claro para utilizar la cláusula HAVING, ya que no necesitamos filtrar por registro. (No vamos a descartar el registro de una persona porque gane menos de 100.000 dólares). La idea es filtrar en base a los ingresos familiares, por lo que necesitamos agrupar a las personas por last_name y utilizar HAVING para filtrar los grupos de personas, como se muestra a continuación:

Texto de la consulta para copiar y pegar:

SELECT 	last_name,
		SUM(year_income) AS "family_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income) > 100000;

WHERE vs HAVING

CLÁUSULAS COMPLEJAS HAVING

Podemos utilizar tantas funciones agregadas como queramos en la condición de la cláusula HAVING. Sigamos con nuestro análisis de los ingresos familiares y calculemos los ingresos medios por miembro de cada familia. Queremos identificar las familias que ganan menos de 50.000 por persona. Desde el punto de vista económico, este análisis puede mostrar más sobre los ingresos familiares que el anterior. Esta es la consulta:

Texto de la consulta para copiar y pegar:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income)  / COUNT(*) < 50000;

WHERE vs HAVING

Nota: La cláusula HAVING tiene algunas restricciones; una de ellas es que las columnas a nivel de registro en la condición HAVING también deben aparecer en la cláusula GROUP BY.

Uso de WHERE y HAVING en la misma consulta SQL

Es muy común utilizar WHERE y HAVING en la misma consulta. Hagamos una consulta para obtener el ingreso familiar total y el ingreso por miembro de las familias de Oklahoma que tienen más de cuatro miembros:

Texto de la consulta para copiar y pegar:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
WHERE city = ‘Oklahoma’
GROUP BY last_name
HAVING COUNT(*) > 4;

WHERE vs HAVING

WHERE y HAVING en consultas complejas

Para terminar el artículo, construiremos una consulta que devuelva las familias con una renta familiar inferior a la renta media de sus ciudades. La parte complicada es la subconsulta que obtiene la renta media de una ciudad determinada. Tenga en cuenta que utilizamos una consulta diferente porque se trata de la renta media por ciudad; no se basa en el número de miembros por familia, sino en el número de familias de esa ciudad, calculado con count(distinct last_name).

Texto de la consulta para copiar y pegar:

SELECT
  last_name, 
  COUNT(*) AS "members", 
  SUM(year_income) AS "family_income",
  SUM(year_income) / COUNT(*) AS "per_member_income"
FROM persons p
GROUP BY last_name
HAVING SUM(year_income) < (
  SELECT 
  SUM(year_income) / COUNT(distinct last_name) 
  FROM persons 
  WHERE city = p.city
);
WHERE vs HAVING

Resuelto: WHERE vs. HAVING en SQL

Hemos revisado varias consultas diferentes que utilizan las cláusulas WHERE y HAVING de SQL. Como hemos mencionado, ambas cláusulas funcionan como filtros, pero cada una se aplica a un nivel de datos diferente. La cláusula WHERE filtra a nivel de registro, mientras que la cláusula HAVING filtra a nivel de grupo.

SQL es un lenguaje súper flexible, y puedes crear millones de combinaciones utilizando las cláusulas WHERE y HAVING. En este punto, me gustaría mencionar un gran curso relacionado con los temas de este artículo: LearnSQL's Cómo crear informes básicos con SQL en SQL. Beneficia a las personas que conocen los fundamentos de SQL y desean mejorar sus habilidades para crear usando informes SQL significativos. Ve más allá - ¡explora SQL!