Más allá de un único GROUP BY
Agregue en varios niveles
Más allá de un único GROUP BY es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.
La limitación de un único GROUP BY
Una cláusula GROUP BY estándar permite agregar filas en un nivel específico; por ejemplo, calcular las ventas totales por región. Pero ¿qué ocurre si también quiere obtener los totales por categoría de producto y un total general, todo en la misma consulta?
Repetir la consulta tres veces y utilizar UNION ALL funciona, pero resulta largo y lento. SQL proporciona tres extensiones potentes — GROUPING SETS, ROLLUP y CUBE — que resuelven este problema de forma elegante en una sola pasada.
SELECT region, SUM(amount) AS total_sales
FROM sales
GROUP BY region;Configuración de la tabla de ejemplo
A lo largo de esta lección usaremos una tabla sencilla de sales que registra cada venta con una región, una categoría y un importe. Creémosla y rellenémosla para que todas las consultas siguientes tengan sentido en su contexto.
CREATE TABLE sales (
id SERIAL PRIMARY KEY,
region TEXT,
category TEXT,
amount NUMERIC
);
INSERT INTO sales (region, category, amount) VALUES
('North', 'Electronics', 1200),
('North', 'Clothing', 800),
('South', 'Electronics', 950),
('South', 'Clothing', 600),
('East', 'Electronics', 1100),
('East', 'Clothing', 750);¿Qué son GROUPING SETS?
GROUPING SETS permite definir varios niveles de agrupación independientes dentro de una sola cláusula GROUP BY. Cada conjunto de la lista genera su propio grupo de filas, como si hubiera escrito consultas separadas y las hubiera combinado con UNION ALL.
La sintaxis es: GROUP BY GROUPING SETS ( (col1, col2), (col1), () ). El conjunto vacío () representa el total general de todas las filas.
SELECT region, category, SUM(amount) AS total
FROM sales
GROUP BY GROUPING SETS (
(region, category),
(region),
()
);Lectura del resultado de GROUPING SETS
Al ejecutar una consulta de GROUPING SETS, las filas de los distintos niveles de agrupación se apilan juntas. Las columnas que no forman parte de un conjunto concreto aparecen como NULL en esa fila.
Por ejemplo, una fila que pertenece al conjunto (region) tendrá NULL en la columna category, lo que indica que este total abarca todas las categorías de esa región. La fila del total general (conjunto vacío) tiene NULL tanto en region como en category.
SELECT
COALESCE(region, 'ALL REGIONS') AS region,
COALESCE(category, 'ALL CATEGORIES') AS category,
SUM(amount) AS total
FROM sales
GROUP BY GROUPING SETS (
(region, category),
(region),
()
)
ORDER BY region NULLS LAST, category NULLS LAST;Introducción a ROLLUP
ROLLUP es un atajo para una jerarquía habitual de conjuntos de agrupación. Dadas las columnas (A, B), ROLLUP(A, B) genera automáticamente los conjuntos: (A, B), (A) y ().
Es perfecto para datos jerárquicos, como año, mes y día, o región y categoría. La cantidad de conjuntos generados siempre es n + 1, donde n es el número de columnas indicadas.
-- ROLLUP(region, category) is equivalent to:
-- GROUPING SETS ( (region, category), (region), () )
SELECT region, category, SUM(amount) AS total
FROM sales
GROUP BY ROLLUP(region, category)
ORDER BY region NULLS LAST, category NULLS LAST;ROLLUP con tres niveles
Agregar una tercera columna a ROLLUP amplía la jerarquía con un nivel más. ROLLUP(A, B, C) genera cuatro conjuntos: (A, B, C), (A, B), (A) y ().
En el ejemplo siguiente, year es el nivel más externo y category es el más granular. La consulta produce subtotales en cada paso de la jerarquía, además de una fila de total general.
SELECT
year,
region,
category,
SUM(amount) AS total
FROM (
VALUES
(2024, 'North', 'Electronics', 1200),
(2024, 'North', 'Clothing', 800),
(2024, 'South', 'Electronics', 950),
(2025, 'North', 'Electronics', 1400),
(2025, 'South', 'Clothing', 700)
) AS t(year, region, category, amount)
GROUP BY ROLLUP(year, region, category)
ORDER BY year NULLS LAST, region NULLS LAST, category NULLS LAST;Introducción a CUBE
CUBE es aún más amplio que ROLLUP. Dadas n columnas, genera todas las combinaciones posibles de 2^n de conjuntos de agrupación, incluido el total general.
Para CUBE(region, category), los conjuntos producidos son: (region, category), (region), (category) y (), cuatro conjuntos en total. Esto resulta útil cuando necesita totales transversales en todas las direcciones, no solo siguiendo una única jerarquía.
-- CUBE(region, category) produces:
-- GROUPING SETS ( (region,category), (region), (category), () )
SELECT region, category, SUM(amount) AS total
FROM sales
GROUP BY CUBE(region, category)
ORDER BY region NULLS LAST, category NULLS LAST;CUBE o ROLLUP: cuándo usar cada uno
Elija según si sus dimensiones tienen una jerarquía natural:
- Utilice ROLLUP cuando las columnas sean jerárquicas, por ejemplo, de país a ciudad y a tienda. Los subtotales solo ascienden por una ruta.
- Utilice CUBE cuando las columnas sean dimensiones independientes, por ejemplo, región y categoría, y quiera obtener todas las combinaciones posibles.
- Utilice GROUPING SETS cuando necesite un control total y ni ROLLUP ni CUBE se ajusten exactamente a sus requisitos.
La función GROUPING()
Dado que NULL puede significar tanto un valor ausente real como un marcador de agrupación, SQL proporciona la función GROUPING(). Devuelve 1 cuando la columna forma parte de una fila de superagregado (marcador) y 0 cuando la columna se agrupó realmente.
Esto permite distinguir un NULL real en region de una fila de subtotal que abarca todas las regiones.
SELECT
region,
category,
SUM(amount) AS total,
GROUPING(region) AS is_region_subtotal,
GROUPING(category) AS is_category_subtotal
FROM sales
GROUP BY CUBE(region, category)
ORDER BY region NULLS LAST, category NULLS LAST;Usar GROUPING() para etiquetar filas
Un patrón habitual consiste en combinar GROUPING() con una expresión CASE para generar etiquetas legibles en lugar de valores NULL sin procesar. Esto facilita mucho la lectura del resultado de una consulta de ROLLUP o CUBE en los informes.
SELECT
CASE GROUPING(region)
WHEN 1 THEN 'Grand Total'
ELSE region
END AS region_label,
CASE GROUPING(category)
WHEN 1 THEN 'All Categories'
ELSE category
END AS category_label,
SUM(amount) AS total
FROM sales
GROUP BY ROLLUP(region, category)
ORDER BY GROUPING(region), region, GROUPING(category), category;Combinar columnas fijas con ROLLUP
Puede combinar columnas normales de GROUP BY con ROLLUP o CUBE en la misma cláusula. Las columnas indicadas fuera de ROLLUP(...) siempre se incluyen en cada conjunto de agrupación: nunca se resumen en niveles superiores.
En la consulta siguiente, year es una columna de agrupación fija, mientras que region y category participan en el resumen progresivo. Esto significa que obtiene subtotales por año, no un único resultado para todos los años.
SELECT
2024 AS year,
region,
category,
SUM(amount) AS total
FROM sales
GROUP BY 2024, ROLLUP(region, category)
ORDER BY region NULLS LAST, category NULLS LAST;Comprobación rápida
Compruebe su comprensión de GROUPING SETS, ROLLUP y CUBE.
Resumen: más allá de un solo GROUP BY
En esta lección aprendió tres potentes extensiones de SQL que permiten producir varios niveles de agregación en una sola consulta:
- GROUPING SETS: control manual total; enumere exactamente las combinaciones que necesita.
- ROLLUP: ideal para jerarquías; resume desde el nivel más detallado hasta el total general.
- CUBE: genera todas las posibles combinaciones transversales de las dimensiones indicadas.
También aprendió que GROUPING() distingue los valores NULL reales de las filas de superagregado que actúan como marcadores, y que los patrones CASE GROUPING(...) producen resultados limpios y legibles para los informes.
Estas herramientas son indispensables siempre que necesite resúmenes multidimensionales: los informes tipo tabla dinámica, los paneles y las consultas de almacenes de datos dependen en gran medida de ellas.
Preguntas frecuentes
¿La lección «Más allá de un único GROUP BY» es gratis?
Sí — el texto completo de «Más allá de un único GROUP BY» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Más allá de un único GROUP BY»?
Agregue en varios niveles Practicas SQL Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar SQL Academy?
No se requiere experiencia previa. SQL Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Más allá de un único GROUP BY»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de SQL Academy?
Sí. Cada lección de SQL Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Más allá de un único GROUP BY
- ROLLUP para subtotales
- CUBE para todas las combinaciones
- GROUPING SETS explicado