locked
Ajuda para Montar um CROSS TABLE RRS feed

  • Pergunta

  • Fala Galera, blz?
    Estou com um pobleminha aqui que é o seguinte eu tenho uma consulta que me retorna as seguinte informação.
    Estabelecimento       Produto     Mes                   Qtde       Venda Mes    
    -------------------      --------     -----------------    ---------   -----------    
    Estab 1                   Prod. 1      2009-04-01          10          200            
    Estab 1                   Prod. 1      2009-03-02          50          500             
    Estab 1                   Prod. 3      2009-04-01          30          100            
    Estab 1                   Prod. 3      2009-03-02          50          400             
    Estab 2                   Prod. 2      2009-04-01          30          100             
    Estab 2                   Prod. 2      2009-04-02          60          200             

    Eu gostaria de gerar um cross table desta informação que me retornasse da seguinte maneira
    Estabelecimento       Produto     Mes1                 Mes2                   Qtde1     Qtde2       Venda Mes1     Venda Mes2r
    -------------------      --------     -----------------    -----------------     ---------   ---------   --------------     ---------------------
    Estab 1                   Prod. 1      2009-04-01         2009-04-02         10           50                     200       500
    Estab 1                   Prod. 3      2009-04-01         2009-04-02         30           50                     100       400
    Estab 2                   Prod. 2      2009-04-01         2009-04-02         30           60                     100       200


    Porém, não consigo gerar esta consulta utilizando crosstable. Paa reproduzir este resultado eu criei um cursor, porém acho que é possível realizar sem cursor.. 
    alguém pode me ajudar a montar esta query?

      


    Angelo Mestriner
    terça-feira, 28 de abril de 2009 00:28

Respostas

  • Angelo,

     Você conseguiria fazer isso usando a clausula PIVOT.  Veja o post do gustavo, que é bem interessante: http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!178.entry

    Abraços
    Gilberto neto
    Gilberto Neto Blog: http://gilberto-neto.spaces.live.com/default.aspx
    • Sugerido como Resposta Gilberto Neto terça-feira, 28 de abril de 2009 09:35
    • Marcado como Resposta Angelo Mestriner quarta-feira, 29 de abril de 2009 12:01
    terça-feira, 28 de abril de 2009 09:35
  • Bom Dia,

    O artigo do PIVOT é interessante, mas resolvi colocar uma outra solução extra.

    DECLARE @T TABLE (
    	Estabelecimento VARCHAR(20),
    	Produto VARCHAR(20),
    	Mes SMALLDATETIME,
    	Qtde SMALLINT,
    	VendaMes SMALLINT)
    
    INSERT INTO @T VALUES ('Estab 1','Prod. 1','2009-04-01',10,200)
    INSERT INTO @T VALUES ('Estab 1','Prod. 1','2009-03-02',50,500)
    INSERT INTO @T VALUES ('Estab 1','Prod. 3','2009-04-01',30,100)
    INSERT INTO @T VALUES ('Estab 1','Prod. 3','2009-03-02',50,400)
    INSERT INTO @T VALUES ('Estab 2','Prod. 2','2009-04-01',30,100)
    INSERT INTO @T VALUES ('Estab 2','Prod. 2','2009-04-02',60,200)
    
    ;WITH Res As (
    	SELECT Distinct Estabelecimento, Produto
    	FROM @T),
    
    ResXML As (
    	SELECT Res.*,
    		(SELECT Mes, Qtde, VendaMes
    		FROM @T As T
    		WHERE Res.Estabelecimento = T.Estabelecimento And Res.Produto = T.Produto
    		FOR XML RAW('Dados'), TYPE) As DadosXML
    	FROM Res)
    	
    SELECT Estabelecimento, Produto,
    	DadosXML.value('(/Dados/@Mes)[1]','SMALLDATETIME') As Mes1,
    	DadosXML.value('(/Dados/@Mes)[2]','SMALLDATETIME') As Mes2,
    	DadosXML.value('(/Dados/@Qtde)[1]','SMALLINT') As Qtde1,
    	DadosXML.value('(/Dados/@Qtde)[2]','SMALLINT') As Qtde2,
    	DadosXML.value('(/Dados/@VendaMes)[1]','SMALLINT') As VendaMes1,
    	DadosXML.value('(/Dados/@VendaMes)[2]','SMALLINT') As VendaMes2
    FROM ResXML

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Piores Práticas - Uso do COUNT(*)
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!538.entry
    Classifique as respostas. O seu feedback é imprescindível
    terça-feira, 28 de abril de 2009 11:45

Todas as Respostas

  • Boa Noite,

    A quantidade de meses é fixa ? Qual é o seu SQL Server ?

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Piores Práticas - Uso do COUNT(*)
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!538.entry
    Classifique as respostas. O seu feedback é imprescindível
    terça-feira, 28 de abril de 2009 01:02
  • Boa noite Gustavo,

    Respondendo:
    Sim. A qtde de meses é fixa, sempre será dois meses (um atual e outro aterior) e a chave é: Estelecimento / Produto.

    Estou utilizando sql 2005.

    Abraços.

    Angelo Mestriner
    terça-feira, 28 de abril de 2009 01:47
  • Angelo,

     Você conseguiria fazer isso usando a clausula PIVOT.  Veja o post do gustavo, que é bem interessante: http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!178.entry

    Abraços
    Gilberto neto
    Gilberto Neto Blog: http://gilberto-neto.spaces.live.com/default.aspx
    • Sugerido como Resposta Gilberto Neto terça-feira, 28 de abril de 2009 09:35
    • Marcado como Resposta Angelo Mestriner quarta-feira, 29 de abril de 2009 12:01
    terça-feira, 28 de abril de 2009 09:35
  • Bom Dia,

    O artigo do PIVOT é interessante, mas resolvi colocar uma outra solução extra.

    DECLARE @T TABLE (
    	Estabelecimento VARCHAR(20),
    	Produto VARCHAR(20),
    	Mes SMALLDATETIME,
    	Qtde SMALLINT,
    	VendaMes SMALLINT)
    
    INSERT INTO @T VALUES ('Estab 1','Prod. 1','2009-04-01',10,200)
    INSERT INTO @T VALUES ('Estab 1','Prod. 1','2009-03-02',50,500)
    INSERT INTO @T VALUES ('Estab 1','Prod. 3','2009-04-01',30,100)
    INSERT INTO @T VALUES ('Estab 1','Prod. 3','2009-03-02',50,400)
    INSERT INTO @T VALUES ('Estab 2','Prod. 2','2009-04-01',30,100)
    INSERT INTO @T VALUES ('Estab 2','Prod. 2','2009-04-02',60,200)
    
    ;WITH Res As (
    	SELECT Distinct Estabelecimento, Produto
    	FROM @T),
    
    ResXML As (
    	SELECT Res.*,
    		(SELECT Mes, Qtde, VendaMes
    		FROM @T As T
    		WHERE Res.Estabelecimento = T.Estabelecimento And Res.Produto = T.Produto
    		FOR XML RAW('Dados'), TYPE) As DadosXML
    	FROM Res)
    	
    SELECT Estabelecimento, Produto,
    	DadosXML.value('(/Dados/@Mes)[1]','SMALLDATETIME') As Mes1,
    	DadosXML.value('(/Dados/@Mes)[2]','SMALLDATETIME') As Mes2,
    	DadosXML.value('(/Dados/@Qtde)[1]','SMALLINT') As Qtde1,
    	DadosXML.value('(/Dados/@Qtde)[2]','SMALLINT') As Qtde2,
    	DadosXML.value('(/Dados/@VendaMes)[1]','SMALLINT') As VendaMes1,
    	DadosXML.value('(/Dados/@VendaMes)[2]','SMALLINT') As VendaMes2
    FROM ResXML

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Piores Práticas - Uso do COUNT(*)
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!538.entry
    Classifique as respostas. O seu feedback é imprescindível
    terça-feira, 28 de abril de 2009 11:45
  • Gustavo,

     Boa idéia... :)

     Lógico que pivot, acho que ainda tá mais tranquilo. :) nesse caso ai ele teria que entender um pouco de xml, xpath, etc. :)

     Mas eh uma saída sim.  Preciso praticar mais xml, na prática ainda não fiz nada em produção. só brincadeiras mesmo :)

     

    Abraços
    Gilberto Neto


    Gilberto Neto Blog: http://gilberto-neto.spaces.live.com/default.aspx
    terça-feira, 28 de abril de 2009 12:24
  • Oi Gilberto,

    O negócio é que o PIVOT é muito bom para mostrar uma característica, mas no caso há mais de uma. Além de pivotear é necessário para cada mês mostrar a quantidade e a vendames. Aí as coisas começam a ficar complicadas...

    XML na minha opinião é um dos maiores avanços no TSQL que a Microsoft realizou. É impressionante a inúmera quantidade de consultas que passaram a ser possíveis por conta do XML. Acho que se fosse fazer isso no 2000 eu estaria muito encrencado...

    Tenho alguns materiais legais em XML:

    http://www.plugmasters.com.br/sys/categorias/Programa%E7%E3o/XML/

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Piores Práticas - Uso do COUNT(*)
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!538.entry
    Classifique as respostas. O seu feedback é imprescindível
    terça-feira, 28 de abril de 2009 13:50
  • Obrigado a todos..
    resolvido o problema.
    Angelo Mestriner
    quarta-feira, 29 de abril de 2009 12:01
  • Amigo,

     Precisando estamos aqui pra ajudar.

    Abraços
    Gilberto Neto
    Gilberto Neto Blog: http://gilberto-neto.spaces.live.com/default.aspx
    quarta-feira, 29 de abril de 2009 12:20