none
Mostrar todos os dias RRS feed

  • Pergunta

  •  

    Olá a todos.

     

    Tenho uma consulta no SQL que me retorna valores por dia, ex.:

     

    Dia                        Valor

    01/09/2008             10,00

    02/09/2008             20,00

    04/09/2008             30,00

    06/09/2008             50,00

     

     

    No exemplo acima, reparem que nos dias 03 e 05 do mês nove não tinha valores por isso ele não mostrou os 2 dias. Pois bem o que eu quero é justamente isso, que mesmo os dias que não tiverem valor, quero que eles sejam mostrados, ex.:

     

    Dia                        Valor

    01/09/2008             10,00

    02/09/2008             20,00

    03/09/2008               0,00

    04/09/2008             30,00

    05/09/2008               0,00

    06/09/2008             50,00

     

     

    Como eu faço isso?

    Obrigado!

    sexta-feira, 12 de setembro de 2008 12:03

Respostas

  • Bom Dia,

     

    É uma pena, pois, o 2005 consegue fazer isso de formas mais interessantes. Em todo caso, segue uma solução 2000 / 2005.

     

    Code Snippet

    CREATE TABLE #tbl (Dia SMALLDATETIME, Valor SMALLMONEY)

     

    INSERT INTO #tbl VALUES ('20080901',10)

    INSERT INTO #tbl VALUES ('20080902',20)

    INSERT INTO #tbl VALUES ('20080904',30)

    INSERT INTO #tbl VALUES ('20080906',50)

     

    DECLARE @minData SMALLDATETIME, @maxData SMALLDATETIME

    SELECT @minData = MIN(Dia), @maxData = MAX(Dia)

    FROM #tbl

    DECLARE @tbl TABLE (Data SMALLDATETIME)

     

    WHILE @minData <= @maxData

    BEGIN

    INSERT INTO @tbl VALUES (@minData)

    SET @minData = @minData + 1

    END

     

    SELECT Data, ISNULL(Valor,0) AS Valor

    FROM @tbl AS T

    LEFT OUTER JOIN #tbl ON T.Data = #tbl.Dia

     

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 14:42
  • Boa Tarde,

     

    O problema é que seu JOIN está incorretamente formulado. Você pode fazer o seguinte:

     

    Code Snippet

    select T.Data, Isnull(Sum(metros),0) as Metros, Isnull(Sum(peso),0)

    from @tbl T Left Outer Join #TBRomaneio R on (T.data=R.data)

    left join #TBItensRom IR on (R.Romaneio=IR.romaneio)

    left join #Saldos S on (ir.peca=s.peca)

    group by T.Data

     

     

    Embora o conceitualmente mais correto seja:

     

    Code Snippet

    select T.Data, Isnull(Sum(metros),0) as Metros, Isnull(Sum(peso),0)

    from @tbl T Left Outer Join

    (#TBRomaneio R

    inner join #TBItensRom IR on (R.Romaneio=IR.romaneio)

    inner join #Saldos S on (ir.peca=s.peca))

    on (T.data=R.data)

    group by T.Data

     

     

    O primeiro dá brechas a inconsistências em potencial.

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 19:16

Todas as Respostas

  • Bom Dia,

     

    Seu SQL Server é 2005 ?

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 12:14
  •  

    Gustavo, trabalho tanto com o SQL 2000 como com o 2005. Então teria que saber nos dois.

     

     

    Obrigado!

    sexta-feira, 12 de setembro de 2008 12:37
  • Bom Dia,

     

    É uma pena, pois, o 2005 consegue fazer isso de formas mais interessantes. Em todo caso, segue uma solução 2000 / 2005.

     

    Code Snippet

    CREATE TABLE #tbl (Dia SMALLDATETIME, Valor SMALLMONEY)

     

    INSERT INTO #tbl VALUES ('20080901',10)

    INSERT INTO #tbl VALUES ('20080902',20)

    INSERT INTO #tbl VALUES ('20080904',30)

    INSERT INTO #tbl VALUES ('20080906',50)

     

    DECLARE @minData SMALLDATETIME, @maxData SMALLDATETIME

    SELECT @minData = MIN(Dia), @maxData = MAX(Dia)

    FROM #tbl

    DECLARE @tbl TABLE (Data SMALLDATETIME)

     

    WHILE @minData <= @maxData

    BEGIN

    INSERT INTO @tbl VALUES (@minData)

    SET @minData = @minData + 1

    END

     

    SELECT Data, ISNULL(Valor,0) AS Valor

    FROM @tbl AS T

    LEFT OUTER JOIN #tbl ON T.Data = #tbl.Dia

     

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 14:42
  •  

    Gustavo, por favor, se não for encomodo, me passe como o SQL 2005 faz isso dessa forma mais interessante.

     

    Pode ser muito útil para mim.

     

     

    Obrigado!

    sexta-feira, 12 de setembro de 2008 15:00
  • Olá Sandro,

     

    A solução baseada no 2000 lhe atendeu ? Ela resolveu o seu problema ?

    A solução baseada no 2005 eu já postei em algumas Threads por aqui.

    Pesquisa no fórum pelo termo "Montagem de Período"

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 16:16
  • Sandro,

     

    Veja se este exemplo ajuda:

     

    Code Snippet

    Declare @TBVenda Table (Ano Int,Valor Int)

     

    Insert Into @TBVenda Values (2004,1)

    Insert Into @TBVenda Values (2004,2)

    Insert Into @TBVenda Values (2004,3)

    Insert Into @TBVenda Values (2004,4)

     

    Insert Into @TBVenda Values (2005,1)

    Insert Into @TBVenda Values (2005,3)

    Insert Into @TBVenda Values (2005,5)

    Insert Into @TBVenda Values (2005,7)

     

    Insert Into @TBVenda Values (2007,2)

    Insert Into @TBVenda Values (2007,4)

    Insert Into @TBVenda Values (2007,6)

    Insert Into @TBVenda Values (2007,8)

     

    Insert Into @TBVenda Values (2008,4)

    Insert Into @TBVenda Values (2008,8)

    Insert Into @TBVenda Values (2008,12)

    Insert Into @TBVenda Values (2008,16)

     

    Declare @TabelaAno Table (Ano Int)

     

    Insert Into @TabelaAno Values(2004)

    Insert Into @TabelaAno Values(2005)

    Insert Into @TabelaAno Values(2006)

    Insert Into @TabelaAno Values(2007)

    Insert Into @TabelaAno Values(2008)

     

    SELECT IsNull(TB.Ano,TA.Ano),

           Sum(IsNull(Tb.Valor,1))

    FROM @TBVenda TB Right Join @TabelaAno TA

    On TB.Ano = TA.Ano

    GROUP BY TB.Ano, TA.Ano

     

     

     

    sexta-feira, 12 de setembro de 2008 16:24
  • Sandro,

     

    Veja se este exemplo ajuda:

     

    Code Snippet

    Declare @TBVenda Table (Ano Int,Valor Int)

     

    Insert Into @TBVenda Values (2004,1)

    Insert Into @TBVenda Values (2004,2)

    Insert Into @TBVenda Values (2004,3)

    Insert Into @TBVenda Values (2004,4)

     

    Insert Into @TBVenda Values (2005,1)

    Insert Into @TBVenda Values (2005,3)

    Insert Into @TBVenda Values (2005,5)

    Insert Into @TBVenda Values (2005,7)

     

    Insert Into @TBVenda Values (2007,2)

    Insert Into @TBVenda Values (2007,4)

    Insert Into @TBVenda Values (2007,6)

    Insert Into @TBVenda Values (2007,8)

     

    Insert Into @TBVenda Values (2008,4)

    Insert Into @TBVenda Values (2008,8)

    Insert Into @TBVenda Values (2008,12)

    Insert Into @TBVenda Values (2008,16)

     

    Declare @TabelaAno Table (Ano Int)

     

    Insert Into @TabelaAno Values(2004)

    Insert Into @TabelaAno Values(2005)

    Insert Into @TabelaAno Values(2006)

    Insert Into @TabelaAno Values(2007)

    Insert Into @TabelaAno Values(2008)

     

    SELECT IsNull(TB.Ano,TA.Ano),

           Sum(IsNull(Tb.Valor,1))

    FROM @TBVenda TB Right Join @TabelaAno TA

    On TB.Ano = TA.Ano

    GROUP BY TB.Ano, TA.Ano

     

     

     

    sexta-feira, 12 de setembro de 2008 16:24
  • Gustavo e Junior, eu adaptei o exemplo do Gustavo a minha query mas não deu certo. Então fiz um script que se assemelha com o que eu tenho aqui e vou postar abaixo. Por favor, rodem e vejam que não aparecem todos os dias, pq????????

     

     

    Code Snippet

    CREATE TABLE #TBRomaneio (Romaneio int, Data SmallDateTime)

    Insert Into #TBRomaneio Values (1,'20080901')

    Insert Into #TBRomaneio Values (2,'20080902')

    Insert Into #TBRomaneio Values (3,'20080903')

    Insert Into #TBRomaneio Values (4,'20080905')

    Insert Into #TBRomaneio Values (5,'20080906')

    Insert Into #TBRomaneio Values (6,'20080908')

    Insert Into #TBRomaneio Values (7,'20080909')

     

    CREATE TABLE #TBItensRom (Romaneio int, peca int)

    Insert Into #TBItensRom Values (1,1)

    Insert Into #TBItensRom Values (1,2)

    Insert Into #TBItensRom Values (2,3)

    Insert Into #TBItensRom Values (2,4)

    Insert Into #TBItensRom Values (3,5)

    Insert Into #TBItensRom Values (3,6)

    Insert Into #TBItensRom Values (4,7)

    Insert Into #TBItensRom Values (5,8)

    Insert Into #TBItensRom Values (6,9)

    Insert Into #TBItensRom Values (6,10)

    Insert Into #TBItensRom Values (7,11)

     

    CREATE TABLE #Saldos (peca int, Metros Decimal(5,2), Peso Decimal(5,2))

    Insert Into #Saldos Values (1,'10.00','5.00')

    Insert Into #Saldos Values (2,'15.50','7.20')

    Insert Into #Saldos Values (3,'20.00','6.30')

    Insert Into #Saldos Values (4,'30.00','15.00')

    Insert Into #Saldos Values (5,'8.00','2.00')

    Insert Into #Saldos Values (6,'7.00','3.00')

    Insert Into #Saldos Values (7,'60.00','35.00')

    Insert Into #Saldos Values (8,'54.00','20.50')

    Insert Into #Saldos Values (9,'23.00','11.00')

    Insert Into #Saldos Values (10,'46.00','19.00')

    Insert Into #Saldos Values (11,'10.00','3.00')

     

    DECLARE @minData SMALLDATETIME, @maxData SMALLDATETIME

    SELECT @minData = MIN(Data), @maxData = MAX(Data)

    FROM #TBRomaneio

    DECLARE @tbl TABLE (Data SMALLDATETIME)

    WHILE @minData <= @maxData

    BEGIN

    INSERT INTO @tbl VALUES (@minData)

    SET @minData = @minData + 1

    END

     

    select T.Data, Isnull(Sum(metros),0) as Metros, Isnull(Sum(peso),0)

    from @tbl T Left Outer Join #TBRomaneio R on (T.data=R.data)

    inner join #TBItensRom IR on (R.Romaneio=IR.romaneio)

    inner join #Saldos S on (ir.peca=s.peca)

    group by T.Data

     

     

    Obrigado!

    sexta-feira, 12 de setembro de 2008 19:11
  • Sandro,

     

    Então os dias que estão faltando não são retornados?

    sexta-feira, 12 de setembro de 2008 19:14
  • Não.......

     

    Mas o que eu quero é que sejam retornados......Mesmo que não tenho dados para esses dias.

     

     

    Obrigado!

    sexta-feira, 12 de setembro de 2008 19:16
  • Boa Tarde,

     

    O problema é que seu JOIN está incorretamente formulado. Você pode fazer o seguinte:

     

    Code Snippet

    select T.Data, Isnull(Sum(metros),0) as Metros, Isnull(Sum(peso),0)

    from @tbl T Left Outer Join #TBRomaneio R on (T.data=R.data)

    left join #TBItensRom IR on (R.Romaneio=IR.romaneio)

    left join #Saldos S on (ir.peca=s.peca)

    group by T.Data

     

     

    Embora o conceitualmente mais correto seja:

     

    Code Snippet

    select T.Data, Isnull(Sum(metros),0) as Metros, Isnull(Sum(peso),0)

    from @tbl T Left Outer Join

    (#TBRomaneio R

    inner join #TBItensRom IR on (R.Romaneio=IR.romaneio)

    inner join #Saldos S on (ir.peca=s.peca))

    on (T.data=R.data)

    group by T.Data

     

     

    O primeiro dá brechas a inconsistências em potencial.

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 12 de setembro de 2008 19:16
  • Maia,

     

    É verdade, mas utilizando o Inner Join ele vai retornar somente os dados que estejam relacionados!!!

     

     

     

    sexta-feira, 12 de setembro de 2008 19:23
  • Oi Jr.

     

    Quanto ao INNER JOIN, sua afirmação é o raciocínio padrão. De fato, por essa linha de raciocínio, o INNER JOIN só trará os dados presentes nas tabelas do JOIN. Só que o raciocínio padrão não é o 100% correto (principalmente se forçarmos o otimizador a seguir certos caminhos).

     

    Se você testar a consulta com o INNER JOIN (a que postei por último), verá que todos os dias são retornados.

     

    [ ]s,

     

    Gustavo

    sexta-feira, 12 de setembro de 2008 22:30