none
Como podría añadir filas a un resultado? RRS feed

  • Pregunta

  • Muy buenas grupo, tengo 4 familias (A,B,C,D) y X sucursales, quiero sacar el total agrupado por sucursal, el problema es q no se venden todas las familias por día/sucursal, os pongo un script de ejemplo:

    use tempdb;
    drop TABLE dbo.[TotalesFamilia];
    CREATE TABLE dbo.[TotalesFamilia](
        [idsucursal] [varchar](10) NOT NULL,
        [fecha] [datetime] NOT NULL,
        [idFamilia] [varchar](10) NOT NULL,
        [total] [decimal](38, 20) NULL
    );
    
    insert into dbo.[TotalesFamilia] (idsucursal,fecha,idfamilia,total)
    values('1','20160101','A',10),
    ('1','20160101','B',5),
    ('1','20160101','C',12),
    ('2','20160101','A',30),
    ('2','20160101','B',30)
    
    
    
    select idsucursal,fecha,idfamilia,sum(total) as total
    from dbo.[TotalesFamilia]
    group by idsucursal,fecha,idfamilia

    En la consulta me gustaría añadir al resultado las familias que le faltan (A,B,C,D).

    En los reports suelo solucionarlo con el pivot y en una matrix, pero a nivel de consulta, me gustaría saber cual es la forma más óptima, podríais echarme un cable?

    Muchas gracias por leerme


    martes, 13 de diciembre de 2016 10:14

Respuestas

  • Aquí tienes una idea:

    ;with Totalizacion AS (
      select idsucursal,fecha, idfamilia,sum(total) as total
      from TotalesFamilia
      group by idsucursal, fecha, idfamilia
    ),
    Combinaciones AS (
      SELECT DISTINCT A.IdSucursal, B.Fecha, C.IdFamilia
      FROM TotalesFamilia A, TotalesFamilia B, TotalesFamilia C
    )
    SELECT * FROM Totalizacion
    UNION
    SELECT *,0 FROM Combinaciones C
     WHERE NOT EXISTS (SELECT * FROM Totalizacion
                    WHERE C.IdSucursal=IdSucursal
        AND C.IdFamilia=IdFamilia AND C.Fecha=Fecha)

    • Marcado como respuesta osoage martes, 13 de diciembre de 2016 14:27
    martes, 13 de diciembre de 2016 12:09
  • pelos,

    Otra forma es estableciendo el par { sucursal -> todas las familias }, y sobre ese conjunto combinar las filas mediante OUTER JOIN:

    WITH Agrupacion AS
    (
        SELECT
    	   tf.idsucursal, f.idfamilia
        FROM
    	   TotalesFamilia tf
    	   CROSS APPLY (VALUES ('A'), ('B'), ('C'), ('D')) f (idfamilia)
        GROUP BY
    	   tf.idsucursal, f.idfamilia
    )
    SELECT
        a.idsucursal, a.idfamilia, tf.fecha, ISNULL(SUM(tf.total), 0) AS [Total]
    FROM
        Agrupacion a
        LEFT JOIN TotalesFamilia tf ON (a.idsucursal = tf.idsucursal)
    	   AND (a.idfamilia = tf.idFamilia)
    GROUP BY
        a.idsucursal, a.idfamilia, tf.fecha;



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.

    • Marcado como respuesta osoage martes, 13 de diciembre de 2016 16:31
    martes, 13 de diciembre de 2016 15:46

Todas las respuestas

  • Aquí tienes una idea:

    ;with Totalizacion AS (
      select idsucursal,fecha, idfamilia,sum(total) as total
      from TotalesFamilia
      group by idsucursal, fecha, idfamilia
    ),
    Combinaciones AS (
      SELECT DISTINCT A.IdSucursal, B.Fecha, C.IdFamilia
      FROM TotalesFamilia A, TotalesFamilia B, TotalesFamilia C
    )
    SELECT * FROM Totalizacion
    UNION
    SELECT *,0 FROM Combinaciones C
     WHERE NOT EXISTS (SELECT * FROM Totalizacion
                    WHERE C.IdSucursal=IdSucursal
        AND C.IdFamilia=IdFamilia AND C.Fecha=Fecha)

    • Marcado como respuesta osoage martes, 13 de diciembre de 2016 14:27
    martes, 13 de diciembre de 2016 12:09
  • Muchas gracias Aníbal por tu ejemplo, sólo falta que no añade fila en el caso de no existir para ninguna de las sucursales, por ejemplo la familia D que no está en el ejemplo :(, esto puede ocurrir con cualquier otra familia.

    martes, 13 de diciembre de 2016 12:30
  • Entonces me imagino que las familias y las sucursales están en otras tablas, es así?
    martes, 13 de diciembre de 2016 13:45
  • así es
    martes, 13 de diciembre de 2016 14:03
  • Me imagino que a lo que te refieres es a esto, no? he usado una cte en vez de una tabla para no andar con el script:
    ;with Totalizacion AS (
       select idsucursal,fecha, idfamilia,sum(total) as total
       from TotalesFamilia 
       group by idsucursal, fecha, idfamilia
     ),
    CTE_FAMILIA (idfamilia)
    AS
    (
    	SELECT 'A' as idfamilia
    	union 
    	SELECT 'B' as idfamilia
    	union 
    	SELECT 'C' as idfamilia
    	union 
    	SELECT 'D' as idfamilia
    ),
     Combinaciones AS (
       SELECT DISTINCT A.IdSucursal, B.Fecha, C.IdFamilia 
       FROM TotalesFamilia A, TotalesFamilia B, CTE_FAMILIA C
     )
     SELECT * FROM Totalizacion
     UNION
     SELECT *,0 FROM Combinaciones C
      WHERE NOT EXISTS (SELECT * FROM Totalizacion 
                     WHERE C.IdSucursal=IdSucursal 
         AND C.IdFamilia=IdFamilia AND C.Fecha=Fecha)

    martes, 13 de diciembre de 2016 14:53
  • pelos,

    Otra forma es estableciendo el par { sucursal -> todas las familias }, y sobre ese conjunto combinar las filas mediante OUTER JOIN:

    WITH Agrupacion AS
    (
        SELECT
    	   tf.idsucursal, f.idfamilia
        FROM
    	   TotalesFamilia tf
    	   CROSS APPLY (VALUES ('A'), ('B'), ('C'), ('D')) f (idfamilia)
        GROUP BY
    	   tf.idsucursal, f.idfamilia
    )
    SELECT
        a.idsucursal, a.idfamilia, tf.fecha, ISNULL(SUM(tf.total), 0) AS [Total]
    FROM
        Agrupacion a
        LEFT JOIN TotalesFamilia tf ON (a.idsucursal = tf.idsucursal)
    	   AND (a.idfamilia = tf.idFamilia)
    GROUP BY
        a.idsucursal, a.idfamilia, tf.fecha;



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.

    • Marcado como respuesta osoage martes, 13 de diciembre de 2016 16:31
    martes, 13 de diciembre de 2016 15:46
  • Genial Williams! aunque me valen las dos y funcionan perfectamente, ésta era un poco lo que buscaba, que bueno :)

    Muchas gracias a los dos por su gran ayuda :)

    martes, 13 de diciembre de 2016 16:33