none
GROUPING RRS feed

  • 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ú

    jueves, 6 de octubre de 2016 0:55

Respuestas

  • Pedro Ávila,

    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
    jueves, 6 de octubre de 2016 1:19

Todas las respuestas

  • Pedro Ávila,

    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
    jueves, 6 de octubre de 2016 1:19
  • 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


    jueves, 6 de octubre de 2016 13:17
  • Una consulta por que dice: = 1, ¿Que significa el = 1?
    WHEN (GROUPING(Anio) = 1) THEN 'GRAN TOTAL' 


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    jueves, 6 de octubre de 2016 16:35
  • Pedro Ávila,

    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.
    jueves, 6 de octubre de 2016 16:58