none
Exibir todas as datas buscadas em uma linha mesmo que o conteúdo seja nulo RRS feed

  • Pergunta

  • Olá,

    Tenho um sistema em c# que precisa exibir a data e a quantidade x de ocorrências dentro do intervalo setado pelo usuário, acontece que da forma que fiz o sistema, se  não houver uma ocorrência em uma determinada data, ela não volta com resultado 0 da query do SQL .

    EX:

    Dia ---- Ocorrências

    01 ---- 5

    02 ---- 2

    03 ---- 0

    04 ---- 5

    Dessa forma a tabela gerada na consulta não me retorna a linha com a data 03 - 0 ocorrência.

    Gostaria de saber como fazer pra que essa data apareça no resultado do sql.

    Abaixo está a minha query

    select v.local AS EQUIP, CAST(v.data AS DATE) AS DATA, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 0 THEN 1 ELSE NULL END), 0) AS A1, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 1 THEN 1 ELSE NULL END), 0) AS A2, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 2 THEN 1 ELSE NULL END), 0) AS A3, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 3 THEN 1 ELSE NULL END), 0) AS A4

    FROM            veiculo AS v  INNER JOIN
                             classe AS c ON v.id_classe = c.id_classe
    WHERE        v.data BETWEEN @p1 AND @p2
    GROUP BY v.local
    ORDER BY EQUIP

    Preciso que me retorne todas as datas entre os parâmetros mesmo que não tenha ocorrências.

    Obrigado.


    sexta-feira, 22 de maio de 2015 20:08

Respostas

  • Bom pessoal consegui resolver dentro do código c# mesmo,

    Pra quem um dia tiver o mesmo problema, fica ai a solução:

    Converti a datatable resultada pelo sql em uma list <Lista>,  em seguida fiz outra list <Datas> com todas as datas entre os parâmetros e setando 0 para as classes.

    Depois fiz um for dentro de outro for pra apagar as datas da list <Datas> que tenham a mesma data na lista <Lista> deixando assim somente as datas faltantes. 

    Depois fiz um AddRange entre os 2 lists e obtive meu resultado.

    Obrigado a todos!

    • Marcado como Resposta Gabriel FFarias segunda-feira, 25 de maio de 2015 14:24
    segunda-feira, 25 de maio de 2015 14:24

Todas as Respostas

  • Gabriel, troca o INNER JOIN pelo LEFT JOIN:

    select v.local AS EQUIP, CAST(v.data AS DATE) AS DATA, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 0 THEN 1 ELSE NULL END), 0) AS A1, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 1 THEN 1 ELSE NULL END), 0) AS A2, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 2 THEN 1 ELSE NULL END), 0) AS A3, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 3 THEN 1 ELSE NULL END), 0) AS A4
    
    FROM            veiculo AS v  LEFT JOIN
                             classe AS c ON v.id_classe = c.id_classe
    WHERE        v.data BETWEEN @p1 AND @p2
    GROUP BY v.local
    ORDER BY EQUIP

    sexta-feira, 22 de maio de 2015 20:11
  • Experimente com CTE:


    declare @min int = 1, @max int = 31 ;

    with usuario_cte (id ) as
    (
    select @min as ID  
    union all
    select A.id+1 as ID   from usuario_cte A where A.id <= @max
    )
    select ID, count(id_usuario)  from usuario_cte A  left join cont.TAB_usuario B on A.id = DATEPART(day,data_cadastro)
    group by ID

    sexta-feira, 22 de maio de 2015 20:20
  • Gabriel, troca o INNER JOIN pelo LEFT JOIN:

    select v.local AS EQUIP, CAST(v.data AS DATE) AS DATA, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 0 THEN 1 ELSE NULL END), 0) AS A1, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 1 THEN 1 ELSE NULL END), 0) AS A2, COALESCE (SUM(CASE WHEN c.classe = 'A' AND v.detector = 2 THEN 1 ELSE NULL END), 0) AS A3, COALESCE (SUM(CASE WHEN c.classe = 'A' AND 
                             v.detector = 3 THEN 1 ELSE NULL END), 0) AS A4
    
    FROM            veiculo AS v  LEFT JOIN
                             classe AS c ON v.id_classe = c.id_classe
    WHERE        v.data BETWEEN @p1 AND @p2
    GROUP BY v.local
    ORDER BY EQUIP

    Não deu certo
    sexta-feira, 22 de maio de 2015 20:49
  • Experimente com CTE:


    declare @min int = 1, @max int = 31 ;

    with usuario_cte (id ) as
    (
    select @min as ID  
    union all
    select A.id+1 as ID   from usuario_cte A where A.id <= @max
    )
    select ID, count(id_usuario)  from usuario_cte A  left join cont.TAB_usuario B on A.id = DATEPART(day,data_cadastro)
    group by ID

    Ele criou uma segunda tabela com todas as datas entre os parametros mas na hora do join continua retorando nulo.
    sexta-feira, 22 de maio de 2015 20:50
  • coluna :

    isnull(coluna,0) as NomeColuna

    sexta-feira, 22 de maio de 2015 22:19
  • Deleted
    segunda-feira, 25 de maio de 2015 00:31
  • José,

    Sim eu gostaria que um dia que não houvesse registro fosse exibido a data, com valor 0 em cada coluna A.

    Acontece que simplifiquei aqui a consulta pois as classes vão Até P e ficaria um código gigante, mas o restante é basicamente o mesmo que acontece na A. Por isso ocorre a junção entre veículo e local, para verificar qual é o id da classe que corresponde o id no veículo.

    A tabela veículo grava data e hora.

    Os parâmetros @p1 e @p2 recebem um datetime modificado via código c#, no caso do @p1 ele recebe a data inicial informada pelo usuário com hora 00:00:00 e o @p2 recebe a data final com 23:59:59


    segunda-feira, 25 de maio de 2015 11:01
  • Bom pessoal consegui resolver dentro do código c# mesmo,

    Pra quem um dia tiver o mesmo problema, fica ai a solução:

    Converti a datatable resultada pelo sql em uma list <Lista>,  em seguida fiz outra list <Datas> com todas as datas entre os parâmetros e setando 0 para as classes.

    Depois fiz um for dentro de outro for pra apagar as datas da list <Datas> que tenham a mesma data na lista <Lista> deixando assim somente as datas faltantes. 

    Depois fiz um AddRange entre os 2 lists e obtive meu resultado.

    Obrigado a todos!

    • Marcado como Resposta Gabriel FFarias segunda-feira, 25 de maio de 2015 14:24
    segunda-feira, 25 de maio de 2015 14:24