Principales respuestas
GROUPING

Pregunta
-
Hola
Estoy ejecutando este query
SELECT ProductID, GROUPING(ProductID), OrderID, GROUPING(OrderID), SUM(Quantity) FROM [Order Details] GROUP BY ROLLUP(ProductID, OrderID)
Pero como veo que hay dos GROUPING pensé que se podía usar un solo GROUPING hice esto
SELECT ProductID, OrderID, SUM(Quantity) FROM [Order Details] GROUP BY GROUPING SETS(ProductID, OrderID)
Pero veo que el resultado de este ultimo no es igual al resultado de la primera query. ¿Hay manera de usar un solo GROUPING?.
Pedro Ávila
"El hombre sabio querrá estar siempre con quien sea mejor que él."
Lima - Perú
Respuestas
-
La instrucción GROUPING no es análoga a GROUPING SETS, ocupan funciones distintas. GROUPING retorna 1 o 0 según la expresión de columna es agregada o no. Siguiendo el ejemplo que propuse en otro hilo haremos uso de GROUPING para poner etiquetas en los totales:
DECLARE @Ventas table (Anio int, Mes int, Monto decimal(9,2)); INSERT INTO @Ventas VALUES (2015, 1, 100), (2015, 1, 200), (2016, 1, 300), (2016, 1, 400), (2015, 2, 100), (2016, 2, 200); SELECT CASE WHEN (GROUPING(Anio) = 1) THEN 'GRAN TOTAL' WHEN (GROUPING(Mes) = 1) THEN CONCAT('TOTAL ', Anio) ELSE CONVERT(nvarchar(4), Anio) END AS 'Anio', Mes, SUM(Monto) AS 'Monto Mensual' FROM @Ventas GROUP BY ROLLUP (Anio, Mes);
Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.- Marcado como respuesta Pedro Ávila jueves, 6 de octubre de 2016 1:22
Todas las respuestas
-
La instrucción GROUPING no es análoga a GROUPING SETS, ocupan funciones distintas. GROUPING retorna 1 o 0 según la expresión de columna es agregada o no. Siguiendo el ejemplo que propuse en otro hilo haremos uso de GROUPING para poner etiquetas en los totales:
DECLARE @Ventas table (Anio int, Mes int, Monto decimal(9,2)); INSERT INTO @Ventas VALUES (2015, 1, 100), (2015, 1, 200), (2016, 1, 300), (2016, 1, 400), (2015, 2, 100), (2016, 2, 200); SELECT CASE WHEN (GROUPING(Anio) = 1) THEN 'GRAN TOTAL' WHEN (GROUPING(Mes) = 1) THEN CONCAT('TOTAL ', Anio) ELSE CONVERT(nvarchar(4), Anio) END AS 'Anio', Mes, SUM(Monto) AS 'Monto Mensual' FROM @Ventas GROUP BY ROLLUP (Anio, Mes);
Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.- Marcado como respuesta Pedro Ávila jueves, 6 de octubre de 2016 1:22
-
Para que este ejemplo resulte en el mismo orden de filas (determinista), deberas adicionar la clausula ORDER BY y hacer uso de la funcion GROUPING.
La funcion GROUPING(Anio) devolvera cero si la fila no es resultado de la agrupacion y 1 si esta fila es el resultado de agrupar y agregar los valores por esta columna. El patron es primero sortear por el GROUPING y luego por la columna.
DECLARE @Ventas table (Anio int, Mes int, Monto decimal(9,2)); INSERT INTO @Ventas VALUES (2015, 1, 100), (2015, 1, 200), (2016, 1, 300), (2016, 1, 400), (2015, 2, 100), (2016, 2, 200); SELECT --GROUPING(Anio) AS [GROUPING(Anio)], --GROUPING(Mes) AS [GROUPING(Mes)], CASE WHEN (GROUPING(Anio) = 1) THEN 'GRAN TOTAL' WHEN (GROUPING(Mes) = 1) THEN CONCAT('TOTAL ', Anio) ELSE CONVERT(nvarchar(4), Anio) END AS 'Año', Mes, SUM(Monto) AS 'Monto Mensual' FROM @Ventas GROUP BY ROLLUP (Anio, Mes) ORDER BY GROUPING(Anio), Anio, GROUPING(Mes), Mes; GO
Nota que renombre la columna donde se concatena el [anio] como [Año] para no usar el mismo nombre de la columna de la tabla, la cual se usa en el GROUPING, y poder sortear por ella.
AMB
Some guidelines for posting questions...
AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas- Editado HunchbackMVP jueves, 6 de octubre de 2016 13:18
-
-
GROUPING() sólo retorna 0 o 1, 1 significa que la fila corresponde a la fila de resumen, que son precisamente las filas donde ponemos la etiqueta TOTAL/GRAN TOTAL. Para que te des cuenta, quita el comentario que puso AMB y verifica que valores toma la resultante de GROUPING()
DECLARE @Ventas table (Anio int, Mes int, Monto decimal(9,2)); INSERT INTO @Ventas VALUES (2015, 1, 100), (2015, 1, 200), (2016, 1, 300), (2016, 1, 400), (2015, 2, 100), (2016, 2, 200); SELECT GROUPING(Anio) AS [GROUPING(Anio)], GROUPING(Mes) AS [GROUPING(Mes)], CASE WHEN (GROUPING(Anio) = 1) THEN 'GRAN TOTAL' WHEN (GROUPING(Mes) = 1) THEN CONCAT('TOTAL ', Anio) ELSE CONVERT(nvarchar(4), Anio) END AS 'Año', Mes, SUM(Monto) AS 'Monto Mensual' FROM @Ventas GROUP BY ROLLUP (Anio, Mes) ORDER BY GROUPING(Anio), Anio, GROUPING(Mes), Mes; GO
Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.