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

Cómo utilizar WHERE con GROUP BY en SQL

En este artículo, discutiremos cómo combinar las cláusulas WHERE y GROUP BY en SQL. Si escribe SQL a diario, se dará cuenta rápidamente de la frecuencia con la que se utilizan las cláusulas WHERE y GROUP BY. WHERE es una parte esencial de la mayoría de las consultas. Le permite filtrar grandes conjuntos de datos sólo por las partes que le interesan. GROUP BY es una de las herramientas más potentes de que dispone un analista a la hora de agregar datos. Al final de este artículo, comprenderá cómo utilizar eficazmente estas dos cláusulas y, al mismo tiempo, evitará los errores más comunes.

A la hora de escribir SQL, considere cada cláusula (SELECT, WHERE, GROUP BY, etc.) como una herramienta independiente. A medida que aprendes más sintaxis SQL, añades esa herramienta a tu kit de herramientas. Como puedes imaginar, un mecánico con sólo unas pocas herramientas no será muy eficaz. No le recomendaría que llevara su coche a alguien que sólo tuviera un puñado de herramientas. Lo mismo ocurre con el análisis de datos. Cuantas más herramientas tenga a su disposición, más rápida y eficazmente podrá analizar diferentes conjuntos de datos.

Una de las formas más completas de adquirir herramientas SQL es realizando nuestro curso interactivo SQL para principiantes. Contiene 129 ejercicios y abarca conocimientos básicos e intermedios de SQL, equipándote con todo lo que necesitas aprender para convertirte en un analista de datos eficaz.

Empecemos analizando en profundidad WHERE y GROUP BY por separado. Una vez que hayamos establecido estos conocimientos básicos, combinaremos los dos y liberaremos todo su poder.

La cláusula WHERE

Como se ha indicado anteriormente, la cláusula WHERE se utiliza para filtrar un conjunto de datos y devolver sólo los registros que coinciden con algunos criterios especificados. Consideremos el siguiente conjunto de datos, que incluye las poblaciones de los países para 2022.

A título ilustrativo, diremos que estos datos se encuentran en una tabla denominada world_populations y sólo incluyen los 10 países más poblados. Echaremos un vistazo a estos datos ejecutando:

SELECT *
FROM world_populations

He aquí el resultado:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
China1,439,323,7760.00395,540,09038.61.1847
India1,380,004,3850.009913,586,63128.35.1770
United States331,002,6510.00591,937,73438.83.0425
Indonesia273,523,615.01072,898,04730.56.0351
Pakistan220,892,340.024,327,02223.35.0283
Brazil212,559,41700721,509,89033.88.0273
Nigeria206,139,589.02585,175,99018.52.0264
Bangladesh164,689,383.01011,643,22228.39.0211
Russia145,934,462.000462,20640.74.0187
Mexico128,932,753.01061,357,22429.84.0165

OK, tenemos nuestros datos. Ahora vamos a añadir algunos filtros.

Ejemplo #1

En nuestro primer ejemplo, sólo queremos ver los países cuya población es superior a 200 millones de habitantes. Para ello, ejecutaremos la siguiente consulta:

SELECT *
FROM world_populations
WHERE population > 200000000

Y el resultado:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
China14393237760.0039554009038.61.1847
India13800043850.00991358663128.35.1770
United States3310026510.0059193773438.83.0425
Indonesia273523615.0107289804730.56.0351
Pakistan220892340.02432702223.35.0283
Brazil2125594170.72%15098903388%2.73%
Nigeria2061395892.58%51759901852%2.64%

Podemos ver que la cláusula WHERE filtró Bangladesh, Rusia y México porque sus poblaciones están por debajo del umbral establecido en nuestra consulta.

Ejemplo nº 2

La cláusula WHERE también puede admitir varios filtros. Enumeremos sólo los países que registraron un cambio anual positivo en el número de inmigrantes y en los que al menos el 80% de la población vivía en zonas urbanas. Observe que hemos utilizado AND en la cláusula WHERE para conectar estas dos condiciones:

SELECT *
FROM world_populations
WHERE migrants > 0
  AND urban_pop_pct > .80

Esta consulta devuelve:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
United States3310026510.0059193773438.83.0425
Brazil2125594170.0072150989033.88.0273

No hay límite a la cantidad de filtrado que puede hacer en una cláusula WHERE. Para obtener más información, consulte nuestra Guía completa de la cláusula WHERE de SQL.

La cláusula GROUP BY

Para comprender GROUP BY, utilizaremos un conjunto de datos diferente denominado transactions. Contiene datos transaccionales de un minorista en línea:

DescriptionProductCategoryQuantityUnitPriceCustomerID
KNITTED UNION FLAG HOT WATER BOTTLEKitchen63.3917850
POPPY'S PLAYHOUSE BEDROOMToys62.117850
IVORY KNITTED MUG COSYKitchen61.6513047
BOX OF VINTAGE JIGSAW BLOCKSToys34.9513047
RED COAT RACK PARIS FASHIONClothing34.9513047
YELLOW COAT RACK PARIS FASHIONClothing34.9513047
BLUE COAT RACK PARIS FASHIONClothing34.9513047

Ejemplo nº 1

El operador GROUP BY se utiliza para agregar datos agrupando registros que comparten el mismo valor en un campo especificado. Para responder a la pregunta "¿Cuántos artículos se vendieron en cada categoría de producto?", ejecutaríamos la siguiente consulta:

SELECT 
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
GROUP BY productCategory

Estos son los resultados:

ProductCategoryQuantity
Kitchen12
Toys9
Clothing9

Hay 2 productos en la categoría de productos de cocina: BOTELLA DE AGUA CALIENTE CON BANDERA DE LA UNIÓN y TONTERA DE TEJIDO MARFIL. Cada uno de estos productos tiene una cantidad de 6; por lo tanto, la suma total de la categoría de productos de cocina es de 12.

Hay dos productos en la categoría de juguetes. POPPY'S PLAYHOUSE BEDROOM tiene una cantidad de 6 y BOX OF VINTAGE JIGSAW BLOCKS tiene una cantidad de 3, por lo que la suma total es de 9.

Por último, hay tres productos en la categoría de ropa, cada uno con una cantidad de 3. Esto hace que la suma total de la categoría de ropa sea de 9.

No vamos a repasarlas todas, pero hay muchos tipos de agregaciones a disposición del analista de datos. Entre ellos se incluyen SUM(), AVG(), COUNT(), MEDIAN(), MIN() y MAX(). Encontrará más información en el artículo Cómo utilizar funciones agregadas en la cláusula WHERE.

Ejemplo nº 2

¿Qué pasa si queremos agregar cantidades para cada categoría de producto y cliente? Podemos GROUP BY múltiples columnas:

SELECT 
  customerId,
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
GROUP BY customerId, productCategory

Y este es el resultado:

CustomerIDProductCategoryQuantity
17850Kitchen6
17850Toys6
13047Kitchen6
13047Toys3
13047Clothing9

Podemos ver que hay una fila para cada combinación de cliente y categoría de producto; ahora sabemos cuántos artículos de cada categoría ha comprado cada cliente.

Para más información sobre GROUP BY, consulte Uso de GROUP BY en SQL y Explicación de GROUP BY en SQL.

Uso Conjunto de WHERE y GROUP BY

Ahora que hemos sentado las bases, combinemos WHERE y GROUP BY. Es importante recordar que la cláusula WHERE va a filtrar el conjunto de datos antes de que se evalúe la cláusula GROUP BY. Además, la cláusula WHERE siempre irá antes de GROUP BY. Si la pone después, la consulta devolverá un error.

Ejemplo nº 1

Consideremos el mismo conjunto de datos y pensemos en cómo responderíamos a la pregunta "¿Cuál es el precio unitario medio de los productos de cocina y los juguetes?".

En primer lugar, tendremos que filtrar los productos de cocina y los juguetes. A continuación, calcularemos el precio unitario medio. Esta es la consulta:

SELECT
  productCategory,
  AVG(UnitPrice) as AvgUnitPrice
FROM transactions 
WHERE productCategory in(‘Kitchen’, ‘Toys’)
GROUP BY productCategory

Y el resultado es:

ProductCategoryAvgUnitPrice
Kitchen2.52
Toys3.05

El precio unitario medio se calcula sólo para los productos de cocina y juguetes. Todas las demás categorías quedan excluidas de la consulta.

Ejemplo nº 2

Veamos ahora cómo obtener la cantidad total de productos por categoría cuyo precio unitario medio es superior a 3. Para ello, ejecutaríamos

SELECT
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
WHERE unitPrice > 3
GROUP BY productCategory

En este ejemplo, los agregados se calculan sobre las filas filtradas. Obtenemos el siguiente resultado:

ProductCategoryQuantity
Kitchen6
Toys3
Clothing9

Como sólo los productos BOTTELLA DE AGUA CALIENTE CON BANDERA DE LA UNIÓN, CAJA DE BLOQUES DE JIGSAW VINTAGE, PERCHA ROJA PARIS FASHION, PERCHA AMARILLA PARIS FASHION y PERCHA AZUL PARIS FASHION tienen precios unitarios superiores a 3, éstos son los únicos productos incluidos en la agregación.

Si excluyéramos la cláusula WHERE, obtendríamos los siguientes resultados:

ProductCategoryQuantity
Kitchen12
Toys9
Clothing9

Aquí vemos que se totalizan las cantidades de todos los productos, independientemente del precio unitario. La cantidad total es diferente para todos los productos frente a los productos con un precio unitario superior a 3.

Ejemplo nº 3

¿Qué pasa si queremos filtrar por una columna agregada? Este es el trabajo de la cláusula HAVING. No se puede poner una agregación en la cláusula WHERE. La cláusula HAVING se utiliza en lugar de WHERE cuando se filtra basándose en funciones de agregación. Podemos ilustrar esto con otro ejemplo. Sigamos con el ejemplo anterior y filtremos los resultados por categorías de productos cuyo precio unitario medio sea superior a 3. Para lograrlo, escribiríamos

SELECT
  productCategory 
  AVG(UnitPrice) as AvgUnitPrice
FROM transactions 
WHERE productCategory in (‘Kitchen’, ‘Toys’)
GROUP BY productCategory
HAVING AVG(UnitPrice) > 3

Resultado:

ProductCategoryAvgUnitPrice
Toys3.05

Lo primero que ocurre es que la cláusula WHERE limita los datos sólo a las categorías de cocinas y productos. A continuación, GROUP BY agrega el precio unitario medio de cada categoría. Por último, la cláusula HAVING filtra aún más los resultados para incluir sólo las categorías de productos con un precio unitario medio superior a 3.

Si elimináramos la cláusula HAVING, veríamos que tanto la categoría de cocina como la de juguetes aparecerían en el resultado. Sin embargo, como el precio unitario medio de los artículos de cocina es inferior a 3, se filtra cuando añadimos la cláusula HAVING.

Para más ejemplos, lea nuestro artículo sobre HAVING vs. WHERE en SQL.

WHERE y GROUP BY - ¿Qué hacer a partir de ahora?

¡Buen trabajo! Ha adquirido los conocimientos básicos necesarios para combinar las cláusulas WHERE y GROUP BY en SQL. Ha aprendido la diferencia entre WHERE y HAVING. Y lo que es más importante, puedes combinar estas tres cláusulas para filtrar y agregar datos según tus necesidades.

Ha añadido dos herramientas más a su conjunto de herramientas y está listo para utilizarlas. Una buena forma de reforzar estos conocimientos es seguir nuestro curso interactivo SQL para principiantes. ¡La práctica hace al maestro!

Además, asegúrate de consultar el resto de nuestros magníficos artículos.