26th Feb 2023 Lectura de 9 minutos Cómo Agrupar por Múltiples Columnas en SQL Gustavo du Mortier SQL aprender SQL agrupar por Índice GROUP BY 1 Columna Agrupar por 2 columnas Agrupar por varias columnas Otras formas de utilizar GROUP BY con múltiples columnas Uso de agrupar por varias columnas: Agrupar una jerarquía Uso de agrupar por varias columnas: Agrupación no jerárquica GROUP BY con múltiples columnas devuelve información facetada Al analizar grandes conjuntos de datos, a menudo se crean agrupaciones y se aplican funciones de agregación para encontrar totales o promedios. En estos casos, el uso de la cláusula GROUP BY con varias columnas despliega todo su potencial. GROUP BY es una cláusula del comando SELECT. Permite calcular diversas estadísticas para un grupo de filas. Por ejemplo, puede utilizar GROUP BY con una tabla de empleados para saber cuántos empleados son de cada sexo. O puede agrupar por varias columnas para determinar la edad media de los vehículos de cada marca y modelo en una tabla vehicle_fleet. En este artículo, examinaremos en detalle cómo funciona la agrupación por varias columnas. Este artículo asume que ya sabes cómo utilizar GROUP BY en una consulta SQL. ¿No estás familiarizado con GROUP BY? La mejor forma de aprender ésta y otras construcciones SQL básicas es con nuestro curso interactivo SQL para principiantes. Contiene 129 ejercicios prácticos. Cada ejercicio contiene una breve explicación y una tarea que resolver. Con cada ejercicio completado, ganarás confianza en tus habilidades SQL. Este curso también es una buena forma de repasar las funciones básicas de SQL si tus conocimientos están un poco oxidados. Bien, comencemos con un repaso de un caso de uso simple para GROUP BY. GROUP BY 1 Columna Cada combinación de los valores de columna(s) especificados en la cláusula GROUP BY constituye un grupo; el comando SELECT con una cláusula GROUP BY muestra una sola fila para cada grupo. También es bueno tener en cuenta que GROUP BY permite aplicar funciones de agregado en columnas no incluidas en el subconjunto destacado. Veamos un ejemplo. He creado una tabla llamada WorldWideFriends que almacena datos sobre mis amigos en distintas partes del mundo: FriendNameCityStateCountry MaríaAcapulcoGuerreroMéxico FernandoCaracasDistrito CapitalVenezuela GersonMedellínAntioquíaColombia MónicaBogotáCundinamarcaColombia PaulBogotáCundinamarcaColombia KevinLexingtonKentuckyUSA CeciliaGodoy CruzMendozaArgentina PabloAtlántidaCanelonesUruguay AndreaCdad. MendozaMendozaArgentina MarlonSao PauloSao PauloBrasil JoaoRio de JaneiroRio de JaneiroBrasil AndrésBarilocheRío NegroArgentina MarianoMiamiFloridaUSA Me gustaría utilizar la información de esta tabla para hacer alguna investigación - por ejemplo, para obtener una lista de los países donde viven mis amigos, incluyendo el número de amigos que viven en cada país. Si quisiera saber cuántos amigos tengo en cada país, utilizaría GROUP BY junto con la función de agregado COUNT(): SELECT Country, COUNT(*) AS HowMany FROM WorldWideFriends GROUP BY Country; Esta consulta me da un conjunto de resultados que condensa las filas con el mismo país en una sola fila, mientras que COUNT(*) me dice cuántas filas repetidas hay para cada país: CountryHowMany Argentina3 Venezuela1 Colombia3 Brasil2 USA2 México1 Uruguay1 La consulta anterior me da la información que necesitaría si, por ejemplo, tuviera que elegir a qué país viajar para reunirme con el mayor número posible de amigos. Si quieres leer más sobre el uso básico de GROUP BY, te recomiendo nuestros artículos sobre Qué es GROUP BY en SQL y Cómo utilizar GROUP BY. Sin embargo, aunque viaje a un país en el que viven muchos de mis amigos, puede que éstos se encuentren en distintos estados. Puede que no tenga tiempo de viajar de un estado a otro para visitarlos a todos. Así que tengo que refinar un poco mi búsqueda para encontrar la ubicación geográfica donde hay una mayor concentración de mis amigos. Agrupar por 2 columnas Ahora necesito saber cómo se distribuyen mis amigos por estados y países. Puedo averiguarlo añadiendo la columna State a mi anterior GROUP BY País (separándolas con comas) y en la cláusula SELECT. La consulta queda así SELECT Country, State, COUNT(*) AS HowMany FROM WorldWideFriends GROUP BY Country, State; Observando los resultados de esta consulta, podemos ver que algunos de los países que antes aparecían en una sola fila ahora aparecen en varias filas. La razón es que cuando añadimos el campo State, la consulta debe reunir los grupos con las filas que tienen el mismo valor tanto en Country como en State. En la consulta anterior, la fila correspondiente a 'Colombia' tenía un 3 en el campo HowMany. En este caso, "Colombia" aparece en dos filas con valores diferentes para el Estado: una para "Antioquia" y otra para "Cundinamarca". En el campo HowMany, la fila correspondiente a "Antioquia" indica 1, mientras que la fila correspondiente a "Cundinamarca" indica 2. Esto significa que, en la lista desagregada, hay dos filas con Country = 'Colombia' y State = 'Cundinamarca', y sólo una con Country = 'Colombia' y State = 'Antioquia'. La suma de los valores HowMany de estas dos filas coincide lógicamente con el valor HowMany anterior de la fila correspondiente a 'Colombia'. Lo mismo ocurrirá para cualquiera de los otros países que estén divididos en varias filas con diferentes estados. CountryStateHowMany ArgentinaMendoza2 ArgentinaRío Negro1 VenezuelaDistrito Capital1 ColombiaAntioquía1 ColombiaCundinamarca2 BrasilRio de Janeiro1 BrasilSao Paulo1 USAKentucky1 USAFlorida1 MéxicoGuerrero1 UruguayCanelones1 Agrupar por varias columnas Por último, si mi intención es que mi viaje sea lo más corto posible y aún así visitar al mayor número de amigos, sólo tengo que añadir la columna City a mi consulta -tanto en SELECT como en GROUP BY - para ver qué ciudades tienen el mayor número de amigos: SELECT Country, State, City, COUNT(*) AS HowMany FROM WorldWideFriends GROUP BY Country, State, City; Cuando añadimos columnas a GROUP BY, aumenta el número de filas del resultado. Esto se debe a que crece el número de combinaciones de valores posibles. Cuando añado la columna City al SQL GROUP BY, el tamaño del resultado crece considerablemente: CountryStateCityHowMany ArgentinaMendozaCdad. Mendoza1 ArgentinaMendozaGodoy Cruz1 ArgentinaRío NegroBariloche1 VenezuelaDistrito CapitalCaracas1 ColombiaAntioquíaMedellín1 ColombiaCundinamarcaBogotá2 BrasilRio de JaneiroRio de Janeiro1 BrasilSao PauloSao Paulo1 USAKentuckyLexington1 USAFloridaMiami1 MéxicoGuerreroAcapulco1 UruguayCanelonesAtlántida1 En este caso, creo que sería mejor ver sólo las ciudades en las que hay más de uno de mis amigos. Así que para resumir los resultados, utilizaré la cláusula HAVING. Esta cláusula me permite establecer una condición sobre los resultados de las funciones agregadas al utilizar GROUP BY. En este caso, la condición a aplicar será que el recuento de amigos sea mayor que 1 (COUNT(*) > 1). Tras incorporar la cláusula HAVING, la consulta queda de la siguiente manera: SELECT Country, State, City, COUNT(*) AS HowMany FROM WorldWideFriends GROUP BY Country, State, City HAVING COUNT(*) > 1; De esta forma, el resultado de la consulta se reduce a una única fila que me muestra la única ciudad en la que hay más de uno de mis amigos: CountryStateCityHowMany ColombiaCundinamarcaBogotá2 Otras formas de utilizar GROUP BY con múltiples columnas Es habitual utilizar GROUP BY con múltiples columnas cuando dos o más de las columnas de un resultado de consulta forman una jerarquía de clasificaciones con varios niveles. Este tipo de jerarquías se encuentran en muchos ámbitos, como por ejemplo: Datos detallados de ventas con la fecha de venta dividida en año, trimestre y mes. El catálogo de productos de un fabricante organizado por familia, marca, línea, modelo. La nómina de los empleados de una empresa organizada por dirección, sector, departamento. En todos estos casos, se pueden utilizar diferentes subconjuntos de columnas en GROUP BY para ir de lo general a lo particular. Uso de agrupar por varias columnas: Agrupar una jerarquía Veamos un ejemplo de conjunto de resultados de datos de ventas. Supongamos que tiene una vista llamada ViewSales que devuelve la siguiente información: YearQuarterMonthDateQuantityUnit_Price 202141111/15/2021516.08 2021388/2/2021117.06 2022244/5/2022219.48 2022255/21/2022117.06 202141111/17/2021218.50 2022244/5/2022118.08 2022388/16/2022515.26 Es fácil ver que los primeros campos de esta tabla forman una jerarquía, con el año como nivel superior y la fecha como nivel inferior. Utilizando GROUP BY y la función SUM(), podemos obtener los importes totales de las ventas por Year, por Quarter, por Month o por Date. Si desea obtener el total de unidades vendidas y el precio unitario medio por Year y Quarter, debe especificar esas dos columnas en SELECT y en GROUP BY: SELECT Year, Quarter, SUM(Quantity) AS TotalQty, AVG(Unit_Price) as AvgUnit_Prc FROM ViewSales GROUP BY Year, Quarter; El resultado será: YearQuarterTotalQtyAvgUnit_Prc 20214717.29 20213117.06 20222418.21 20223515.26 Tenga en cuenta que, aunque existe un orden jerárquico, los datos de las distintas columnas de agrupación son independientes entre sí. Esto significa que si agrupa sólo por Quarter en lugar de por Year más Quarter, los cálculos agregados combinarán la información del mismo trimestre para todos los años (es decir, todos los Q2 tendrán una fila): SELECT Quarter, SUM(Quantity) AS TotalQty, AVG(Unit_Price) as AvgUnit_Prc FROM ViewSales GROUP BY Quarter; QuarterTotalQtyAvgUnit_Prc 4717.29 3616.16 2418.21 No se trata de un error, sólo hay que entender que los resultados expresan percepciones diferentes. La segunda consulta permite comparar el rendimiento de las ventas entre distintos trimestres independientemente del año (por ejemplo, para detectar factores estacionales que afectan a las ventas en la misma época de cada año), mientras que la primera compara las ventas de cada año y trimestre en particular. Uso de agrupar por varias columnas: Agrupación no jerárquica En el ejemplo anterior, vimos que agrupar por múltiples columnas nos permite ir de lo general a lo particular cuando tenemos conjuntos de datos con columnas que forman una jerarquía de datos. Pero en situaciones en las que un conjunto de resultados está formado por columnas que no forman una jerarquía, utilizar GROUP BY con múltiples columnas nos permite descubrir verdades ocultas en grandes conjuntos de datos; combina atributos que a primera vista no están relacionados entre sí. Por ejemplo, imaginemos que tenemos una tabla llamada Downloads que almacena información sobre las personas que han descargado películas de un servicio de streaming en los últimos dos años. Esa tabla tiene una fila por cada descarga, y cada fila incluye la siguiente información sobre cada persona que descargó una película: Age Gender Nationality Cada fila también captura estos atributos sobre cada película descargada: Genre Year Country Utilizando GROUP BY con varias de estas columnas y la función COUNT(*), podemos detectar correlaciones entre las columnas. Por ejemplo, para averiguar las preferencias de género de las películas según la edad, escribiríamos: SELECT Age, Genre, COUNT(*) AS Downloads FROM Downloads GROUP BY Age, Genre Como resultados, obtendríamos algo así: AgeGenreDownloads 18Horror12,945 18Comedy15,371 19Drama25,902 19Horror11,038 21Comedy37,408 ……… También podríamos utilizar GROUP BY 3 columnas, para averiguar (por ejemplo) las preferencias de género por sexo y nacionalidad: SELECT Gender, Nationality, Genre, COUNT(*) AS Downloads FROM Downloads GROUP BY Gender, Nationality, Genre Y obtendríamos algo así GenderNationalityGenreDownloads MaleFrenchHorror102,044 MaleFrenchComedy149,290 MaleGermanHorror80,104 FemaleFrenchHorror91.668 FemaleGermanComedy50,103 FemaleGermanDrama61,440 OtherFrenchDrama77,993 OtherGermanComedy25,484 ………… GROUP BY con múltiples columnas devuelve información facetada GROUP BY es una poderosa herramienta para extraer información de grandes conjuntos de datos que son difíciles de manipular de cualquier otra forma. Utilizando GROUP BY con múltiples columnas, puede aprovechar todo su potencial para exponer las verdades de un conjunto de datos, permitiéndole ver diferentes facetas del mismo. Para hacerlo con éxito, es fundamental que entiendas -y sepas explicar- qué representa un conjunto de resultados SQL agrupado por múltiples columnas. Si estás planeando hacer un trabajo serio de análisis de datos, entonces deberías tomar nuestro curso interactivo SQL para principiantes para aprender sobre todas las herramientas que SQL puede ofrecer. Además, sigue estos enlaces si necesitas más explicaciones sobre GROUP BY o quieres ver más ejemplos de GROUP BY en SQL. Tags: SQL aprender SQL agrupar por