Agrupando datos con WITH CUBE, WITH ROLLUP y GROUPING

Por 0 No tags Permalink

En esta entrada mostrare unos ejemplos con los operadores WITH CUBE y WITH ROLLUP, que junto a la función GROUPING resulta de gran utilidad en muchos casos. Explicare el tratamiento de los nulos (NULL) en las consultas WITH CUBE y WITH ROLLUP, y se incluyen varios ejemplos de WITH CUBE y WITH ROLLUP, para facilitar su uso.

¿Cuántos transacciones tenemos de INGRESO y de SALIDA?

se crea una variable de tipo tabla para ver estos ejemplos.

DECLARE @TablaCubeRollup TABLE (ID INT IDENTITY(1,1) NOT NULL, TipoAccionAlmacen VARCHAR(50), Articulo VARCHAR(100), Cantidad INT)
INSERT INTO @TablaCubeRollup (TipoAccionAlmacen, Articulo, Cantidad)
	SELECT 'INGRESO','ARTICULO A','25'
	UNION ALL SELECT 'INGRESO','ARTICULO A','15'
	UNION ALL SELECT 'INGRESO','ARTICULO B','11'
	UNION ALL SELECT 'INGRESO','ARTICULO C','45'
	UNION ALL SELECT 'INGRESO','ARTICULO D','55'
	UNION ALL SELECT 'INGRESO','ARTICULO A','85'
	UNION ALL SELECT 'INGRESO','ARTICULO B','69'
	UNION ALL SELECT 'INGRESO','ARTICULO C','23'
	UNION ALL SELECT 'INGRESO','ARTICULO C','45'
	UNION ALL SELECT 'INGRESO','ARTICULO D','63'
	UNION ALL SELECT 'INGRESO','ARTICULO F','85'
	UNION ALL SELECT 'INGRESO','ARTICULO A','75'
	UNION ALL SELECT 'INGRESO','ARTICULO B','63'
	UNION ALL SELECT 'INGRESO','ARTICULO A','15'
	UNION ALL SELECT 'SALIDA','ARTICULO B','8'
	UNION ALL SELECT 'SALIDA','ARTICULO C','25'
	UNION ALL SELECT 'SALIDA','ARTICULO D','33'
	UNION ALL SELECT 'SALIDA','ARTICULO A','40'
	UNION ALL SELECT 'SALIDA','ARTICULO B','69'
	UNION ALL SELECT 'SALIDA','ARTICULO C','15'
	UNION ALL SELECT 'SALIDA','ARTICULO C','45'
	UNION ALL SELECT 'SALIDA','ARTICULO D','23'
	UNION ALL SELECT 'SALIDA','ARTICULO F','72'
	UNION ALL SELECT 'SALIDA','ARTICULO A','74'
	UNION ALL SELECT 'SALIDA','ARTICULO B','45'

-- ¿Cuántos transacciones tenemos de INGRESO y de SALIDA?
SELECT TipoAccionAlmacen, COUNT(ID) Cantidad
	FROM @TablaCubeRollup GROUP BY TipoAccionAlmacen

¿Qué artículo es el más usada?

SELECT TOP 1 Articulo, SUM(Cantidad) Suma
	FROM @TablaCubeRollup GROUP BY Articulo
	ORDER BY SUM(Cantidad) DESC

¿Cantidad de cada tipo de transacción en cada artículo?

SELECT  TipoAccionAlmacen, Articulo, SUM(Cantidad) Cantidad
	FROM @TablaCubeRollup GROUP BY TipoAccionAlmacen, Articulo 
	ORDER BY TipoAccionAlmacen

¿Y si quiero la información agrupada de más maneras?

Tenemos WITH CUBE que nos permite crear nuevas dimensiones en nuestras consultas. Cuando usamos esta cláusula es como si estuviésemos haciendo a la vez todos los GROUP BY posibles. Añadamos el WITH CUBE a la sentencia anterior.

SELECT  TipoAccionAlmacen, Articulo, SUM(Cantidad) Cantidad
	FROM @TablaCubeRollup GROUP BY TipoAccionAlmacen, Articulo 
	WITH CUBE ORDER BY TipoAccionAlmacen, Articulo

¿Cómo sabemos cuál de los NULL es un super agregado y cual es un NULL de verdad?

Vamos a insertar una nueva fila en nuestra tabla

Existe la función GROUPING que nos dice cuando nuestro NULL es de verdad y cuando no. Esta función nos devuelve un 1 si el nombre de la columna pasada como parámetro se usa como resumen y un 0 si no es así.

-- Vamos a insertar una nueva fila en nuestra tabla
INSERT INTO @TablaCubeRollup (TipoAccionAlmacen, Articulo, Cantidad)
	SELECT 'INGRESO',NULL,'25'

-- ¿Cómo sabemos cual de los NULL es un super agregado y cual es un NULL de verdad?
SELECT TipoAccionAlmacen,
	Articulo, 'Todos los Articulo' = GROUPING(Articulo), 
	SUM(Cantidad) Cantidad
	FROM @TablaCubeRollup GROUP BY TipoAccionAlmacen, Articulo 
	WITH CUBE ORDER BY TipoAccionAlmacen, Articulo

Mejoramos el aspecto del resultado.

Mezclando estas funciones nuevas con dos funciones conocidas, CASE e ISNULL para darle un aspecto más elegante al resultado.

¿Podemos saberlo todo?

Así es, vamos a ejecutar la consulta que nos devuelve toda la información que podemos pedir.

-- Vamos a insertar una nueva fila en nuestra tabla
INSERT INTO @TablaCubeRollup (TipoAccionAlmacen, Articulo, Cantidad)
	SELECT 'INGRESO',NULL,'25'

-- ¿Podemos saberlo todo?
SELECT	'TipoAccionAlmacen'= CASE 
			WHEN GROUPING(TipoAccionAlmacen)=1 THEN 'TODAS'
			ELSE ISNULL(TipoAccionAlmacen, 'N/D')
		END,
	'Articulo'= CASE 
			WHEN GROUPING(Articulo)=1 THEN 'TODAS'
			ELSE ISNULL(Articulo, 'N/D')
		END,			 
	SUM(Cantidad) Cantidad
	FROM @TablaCubeRollup GROUP BY TipoAccionAlmacen, Articulo

¿Y qué pasa con el ROLLUP?

WITH CUBE genera un conjunto de resultados que muestra agregados para todas las combinaciones de valores de las columnas seleccionadas, WHIT ROLLUP retorna agregados para una jerarquía de valores de las columnas seleccionadas.

-- Vamos a insertar una nueva fila en nuestra tabla
INSERT INTO @TablaCubeRollup (TipoAccionAlmacen, Articulo, Cantidad)
	SELECT 'INGRESO',NULL,'25'

-- ¿Y qué pasa con el ROLLUP?
SELECT	'TipoAccionAlmacen'= CASE 
			WHEN GROUPING(TipoAccionAlmacen)=1 THEN 'TODAS'
			ELSE ISNULL(TipoAccionAlmacen, 'N/D')
		END,
	'Articulo'= CASE 
			WHEN GROUPING(Articulo)=1 THEN 'TODAS'
			ELSE ISNULL(Articulo, 'N/D')
		END,			 
	SUM(Cantidad) Cantidad
	FROM @TablaCubeRollup 
	GROUP BY TipoAccionAlmacen, Articulo
	WITH ROLLUP ORDER BY TipoAccionAlmacen, Articulo

Como hemos visto, las cláusulas CUBE, ROLLUP y GROUPING, pueden sernos de gran ayuda, aunque por supuesto, debemos ser conscientes de que la utilización de las agrupaciones no es suele ser una buena práctica de rendimiento (ojo, hablando en términos generales, en el caso de sistemas puramente transaccionales). En entornos de Reporting y Data Warehouse, aportan una gran riqueza al lenguaje SQL.

Compara el precio para envíos nacionales e internacionales con hasta un 70% de ahorro.

No Comments Yet.

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *