none
DATEDIFF ENTRE DUAS LINHAS RRS feed

  • Pergunta

  • COMO POSSO FAZER UM DATADIFF ENTRE DUAS LINHAS(REGISTOS) EM SQL. em uma subquery?

    SELECT DATA, HORA, .....,

    ISNULL((SELECT DATEDIFF(dd,A.DATA,B.DATA) FROM TABELA AS A (NOLOCK)

    WHERE A.Numero=A.Numero AND (A.DATA+A.HORA <= B.DATA+B.HORA) AND A.STAMP <> A.STAMP ),0) AS 'Dias entre datas'

    FROM TABELA AS B (NOLOCK)

    LEFT JOIN TABELA2 AS C (NOLOCK) ON (C.STAMP=C.STAMP)


    Ele da um erro porque retorna mais do que um valor.

    Eu acho que necessito de uma função de agregação, e de um group by para ele ordenar as linhas por data, e depois fazer a diferença com a anterior?



    terça-feira, 21 de agosto de 2012 14:21

Respostas

  • Bem, cara, duas situações:

    1) Seu Order by não está como eu falei: Data, Hora desc. Ele está Data + Hora.

    2) Mesmo colocando Data, Horas desc não dá pra dizer que vai funcionar, pois seu código está conceitualmente diferente do exemplo com Row_Number que venho postando. É possível que só consiga atingir seu objetivo se conseguir utilizar o Row_Number() Over() em sua sintaxe.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta sql-enthusiast sexta-feira, 24 de agosto de 2012 13:59
    sexta-feira, 24 de agosto de 2012 13:49
    Moderador

Todas as Respostas

  • Opa!

    Tem como nos mostrar o que você está pretendendo obter como retorno? Talvez exista uma forma mais apropriada, se tivermos um exemplo do que você tem e pretende obter.


    terça-feira, 21 de agosto de 2012 14:31
  • Segue uma sintaxe de exemplo:

    Create Table #TabelaA (Codigo int, Data DateTime)
    Create Table #TabelaB (Codigo int, Data DateTime)
    
    Insert Into #TabelaA Values (1, '05/10/2012'), (2, '05/14/2012'), (3, '05/22/2012')
    Insert Into #TabelaB Values (1, '05/12/2012'), (2, '05/18/2012'), (3, '05/30/2012')
    
    Select
      A.Data,
      B.Data,
      DiferencaDias = DateDiff(dd, A.Data, B.Data)
    From
      #TabelaA A Left Join #TabelaB B on (B.Codigo = A.Codigo)


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 14:35
    Moderador
  • Pretendo analisar o saldo de um consumidor. Para tal eu necessito de ver, cada linha transaccionada pelo mesmo, assim como o valor em saldo e o numero de dias. O numero de dias é calculado com base na linha anterior, na transacção anterior. É a diferença entre as datas n e n-1, e devolve o valor na linha n. Para tal, ele deve organizar/fazer um order by através da data e para cada consumidor. Eu tenho de forma a que ele está a retornar mais do que um valor, e logo da erro. 
    terça-feira, 21 de agosto de 2012 14:38
  • Segue uma sintaxe de exemplo:

    Create Table #TabelaA (Codigo int, Data DateTime)
    Create Table #TabelaB (Codigo int, Data DateTime)
    
    Insert Into #TabelaA Values (1, '05/10/2012'), (2, '05/14/2012'), (3, '05/22/2012')
    Insert Into #TabelaB Values (1, '05/12/2012'), (2, '05/18/2012'), (3, '05/30/2012')
    
    Select
      A.Data,
      B.Data,
      DiferencaDias = DateDiff(dd, A.Data, B.Data)
    From
      #TabelaA A Left Join #TabelaB B on (B.Codigo = A.Codigo)


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    Realmente não é isto que eu pretendo!
    terça-feira, 21 de agosto de 2012 14:43
  • Para mim ainda está confusa a sua necessidade.

    Consegue postar a estrutura de sua tabela, exemplo de registros e o que você gostaria de retornar?


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 14:49
    Moderador
  • Minha tabela tem a seguinte estrutura:

    STAMP -- NUMERO -- CONSUMIDOR -- DATA -- DATAHORA -- SALDO -- VALORMOEDA -- DIAS???

    1 -- 1 -- "X" -- "2012-10-07 00:00:00.000" -- "2012-10-07 15:14:12.000" --  232 -- 3 -- ???

    2 -- 2 -- "F" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  122 -- 4 -- ???

    3 -- 1 -- "X" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  222 -- 10 -- ??? aqui seria 2, visto  diferença da data reg3-data reg1.

    terça-feira, 21 de agosto de 2012 15:09
  • Então, nesse exemplo que você postou, por que o segundo registro ficou com valor "4"? Essa é a quantidade de dias que representa a diferença entra quais datas?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 16:49
    Moderador
  • Então, nesse exemplo que você postou, por que o segundo registro ficou com valor "4"? Essa é a quantidade de dias que representa a diferença entra quais datas?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    Não, eu corregi!!
    terça-feira, 21 de agosto de 2012 17:02
  • 3 -- 1 -- "X" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  222 -- 10 -- ??? aqui seria 2, visto  diferença da data reg3-data reg1.

    Por que seria a diferença da data do registro 3 para a data do registro 1?

    Não deveria ser entre o registro 3 e o anterior, que é o 2?


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 17:11
    Moderador
  • Não. Tem que ser da 3 para a 1, em que o consumidor e o mesmo!!! isto e conta corrente de consumidor!!
    terça-feira, 21 de agosto de 2012 17:13
  • OK. Entendi. Segue:

    Select
      T1.NUMERO,
      T2.CONSUMIDOR,
      T1.DATA,
      T2.DATA,
      NrDiasDiferenca = DateDiff(dd, T2.DATA, T1.DATA)
    From
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From #Teste) T1 LEFT JOIN
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From #Teste) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                          (T2.NUMERO     = T1.NUMERO)      and
                          (T2.CONSUMIDOR = T1.CONSUMIDOR)
    Order by
      T1.STAMP,
      T1.DATA


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 17:39
    Moderador
  • OK. Entendi. Segue:

    Select
      T1.NUMERO,
      T2.CONSUMIDOR,
      T1.DATA,
      T2.DATA,
      NrDiasDiferenca = DateDiff(dd, T2.DATA, T1.DATA)
    From
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From #Teste) T1 LEFT JOIN
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From #Teste) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                          (T2.NUMERO     = T1.NUMERO)      and
                          (T2.CONSUMIDOR = T1.CONSUMIDOR)
    Order by
      T1.STAMP,
      T1.DATA


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    e como integrar isso do jeito como eu tenho isso acima, quando coloquei a questão
    terça-feira, 21 de agosto de 2012 18:00
  • Acredito que seja mais fácil você me dizer o que ainda falta pra chegar ao que precisa.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 18:06
    Moderador
  • Acredito que seja mais fácil você me dizer o que ainda falta pra chegar ao que precisa.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    Eu tenho meu código assim:

    SELECT STAMP, NUMEROCONSUMIDOR, DATA, HORA, VALORMOEDA, SALDO

    ISNULL((SELECT DATEDIFF(dd,A.DATA,B.DATA) FROM TABELA AS A (NOLOCK)

    WHERE ((A.NUMEROCONSUMIDOR = B.NUMEROCONSUMIDOR)

    AND (A.DATA+B.HORA <= A.DATA+B.HORA)

    AND (A.STAMP <> A.STAMP)),0) AS 'DIAS_ENTRE_DATAS'

    FROM TABELA AS B (NOLOCK)

    LEFT JOIN TABELA2 AS C (NOLOCK) ON (B.STAMP_2=C.STAMP_2)



    Agora quero colocar a parte que vc mencionou, alterando o meu codigo. e de forma a que o resultado seja verdadeiro! :)






    terça-feira, 21 de agosto de 2012 18:56
  • Teoricamente é só utilizar a cláusula From que eu postei anteriormente. Talvez com alguma pequena modificação.

    SELECT
      STAMP,
      NUMERO,
      CONSUMIDOR,
      DATA,
      HORA,
      VALORMOEDA,
      SALDO,
      NrDiasDiferenca = DateDiff(dd, T2.DATA, T1.DATA)
    From
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From Sua_Tabela) T1 LEFT JOIN
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From Sua_Tabela) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                              (T2.NUMERO     = T1.NUMERO)      and
                              (T2.CONSUMIDOR = T1.CONSUMIDOR)


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 19:14
    Moderador
  • Teoricamente é só utilizar a cláusula From que eu postei anteriormente. Talvez com alguma pequena modificação.

    SELECT
      STAMP,
      NUMERO,
      CONSUMIDOR,
      DATA,
      HORA,
      VALORMOEDA,
      SALDO,
      NrDiasDiferenca = DateDiff(dd, T2.DATA, T1.DATA)
    From
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From Sua_Tabela) T1 LEFT JOIN
      (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
       From Sua_Tabela) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                              (T2.NUMERO     = T1.NUMERO)      and
                              (T2.CONSUMIDOR = T1.CONSUMIDOR)


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    Vou verificar.
    terça-feira, 21 de agosto de 2012 19:19
  • Algum resultado?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    terça-feira, 21 de agosto de 2012 19:51
    Moderador
  • Pois, eu nao tenho o banco de dados nesta maquina, e de momento nao posso fazer o teste. Apenas amanha.

    Mas vc acredita qe vai dar? esta vendo a dinamica da questão que coloquei?

    terça-feira, 21 de agosto de 2012 20:41
  • Acontece que o primeiro registo deve ser zero. pois nao tem acomulado. Falta esta verificação. ou seja deve ser 1 quando é null.

    Porisso eu tinha o ISNULL. 

    quarta-feira, 22 de agosto de 2012 10:46
  • Amigo, se você quiser que quando for Nulo venha como zero ou um, basta adicionar a função IsNull, como segue:

    NrDiasDiferenca = IsNull(DateDiff(dd, T2.DATA, T1.DATA), 0)

    Favor marcar todas as respostas que já foram úteis como "útil".


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quarta-feira, 22 de agosto de 2012 11:07
    Moderador
  • Tentei fazer com o top 1 datediff...order by data..

    mas acontece que ele esta a somar o numero de dias com o do registo anterior...

    por exemplo

    se de 1 para 2 são 3 dia e de 2 para 3 são 2 dias ele apresenta:

    1-2

    2-5 e 

    na verdade  deveria devolver:

    1-2

    2-5


    quarta-feira, 22 de agosto de 2012 13:08
  • Coloque um exemplo disso.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quarta-feira, 22 de agosto de 2012 13:11
    Moderador
  • SELECT STAMP, NUMEROCONSUMIDOR, DATA, HORA, VALORMOEDA, SALDO

    ISNULL(

    (SELECT TOP 1 DATEDIFF(dd,A.DATA,B.DATA) FROM TABELA AS A (NOLOCK)

    WHERE ((A.NUMEROCONSUMIDOR = B.NUMEROCONSUMIDOR)

    AND (A.DATA+A.HORA <= B.DATA+B.HORA)

    AND (A.STAMP <> B.STAMP))

    ORDER BY B.DATA+B.HORA)

    ,0) AS 'DIAS_ENTRE_DATAS'

    FROM TABELA AS B (NOLOCK)

    LEFT JOIN TABELA2 AS C (NOLOCK) ON (B.STAMP_2=C.STAMP_2)

    quarta-feira, 22 de agosto de 2012 13:18
  • Não amigo, refiro-me a um exemplo do problema. Coloque alguns registros e explique por favor o que está acontecendo de errado, para que possamos entender.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quarta-feira, 22 de agosto de 2012 13:21
    Moderador
  • Ok, ele tem se ver um consumidor e verificar os seus registos, colocar por ordem , e depois fazer a diferença da data entre o registo atual e o imediatamente anterior.

    Assim, no exemplo que eu apresentei. 

    STAMP -- NUMERO -- CONSUMIDOR -- DATA -- DATAHORA -- SALDO -- VALORMOEDA -- DIAS_ENTRE_DATAS

    1 -- 1 -- "X" -- "2012-10-07 00:00:00.000" -- "2012-10-07 15:14:12.000" --  232 -- 3 -- ???

    2 -- 2 -- "F" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  122 -- 4 -- ???

    3 -- 1 -- "X" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  222 -- 10 -- ???

    4 -- 3 -- "H" -- "2012-10-09 00:00:00.000" -- "2012-10-09 15:15:12.000" --  232 -- 2 -- ???

    5 -- 2 -- "F" -- "2012-10-10 00:00:00.000" -- "2012-10-10 13:14:16.000" --  122 -- 3 -- ???

    6 -- 1 -- "X" -- "2012-10-11 00:00:00.000" -- "2012-10-11 13:16:12.000" --  222 -- 4 -- ???

    Executando isso ai:

    SELECT STAMP, NUMEROCONSUMIDOR, DATA, HORA, VALORMOEDA, SALDO

    ISNULL(

    (SELECT TOP 1 DATEDIFF(dd,A.DATA,B.DATA) FROM TABELA AS A (NOLOCK)

    WHERE ((A.NUMEROCONSUMIDOR = B.NUMEROCONSUMIDOR)

    AND (A.DATA+A.HORA <= B.DATA+B.HORA)

    AND (A.STAMP <> B.STAMP))

    ORDER BY B.DATA+B.HORA)

    ,0) AS 'DIAS_ENTRE_DATAS'

    FROM TABELA AS B (NOLOCK)

    LEFT JOIN TABELA2 AS C (NOLOCK) ON (B.STAMP_2=C.STAMP_2)

    O resultado deveria ficar assim:

    STAMP -- NUMERO -- CONSUMIDOR -- DATA -- DATAHORA -- SALDO -- VALORMOEDA -- DIAS_ENTRE_DATAS

    1 -- 1 -- "X" -- "2012-10-07 00:00:00.000" -- "2012-10-07 15:14:12.000" --  232 -- 3 -- 1

    2 -- 2 -- "F" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  122 -- 4 -- 1

    3 -- 1 -- "X" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  222 -- 10 -- 2

    4 -- 3 -- "H" -- "2012-10-09 00:00:00.000" -- "2012-10-09 15:15:12.000" --  232 -- 2 -- 1

    5 -- 2 -- "F" -- "2012-10-11 00:00:00.000" -- "2012-10-10 13:14:16.000" --  122 -- 3 -- 2

    6 -- 1 -- "X" -- "2012-10-12 00:00:00.000" -- "2012-10-11 13:16:12.000" --  222 -- 4 -- 3

    Mas na verdade o que está acontecer é:

    STAMP -- NUMERO -- CONSUMIDOR -- DATA -- DATAHORA -- SALDO -- VALORMOEDA -- DIAS_ENTRE_DATAS

    1 -- 1 -- "X" -- "2012-10-07 00:00:00.000" -- "2012-10-07 15:14:12.000" --  232 -- 3 -- 1

    2 -- 2 -- "F" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  122 -- 4 -- 1

    3 -- 1 -- "X" -- "2012-10-09 00:00:00.000" -- "2012-10-09 18:14:12.000" --  222 -- 10 -- 3

    4 -- 3 -- "H" -- "2012-10-09 00:00:00.000" -- "2012-10-09 15:15:12.000" --  232 -- 2 -- 1

    5 -- 2 -- "F" -- "2012-10-11 00:00:00.000" -- "2012-10-10 13:14:16.000" --  122 -- 3 -- 3

    6 -- 1 -- "X" -- "2012-10-12 00:00:00.000" -- "2012-10-11 13:16:12.000" --  222 -- 4 -- 6

    Porque esta acontecendo e como solucionar?

    quarta-feira, 22 de agosto de 2012 13:32
  • Ao que tudo indica ficou resolvido. Da mesma forma. Apenas alteração da ORDER BY B.DATA+B.HORA) por ORDER BY a.DATA+a.HORA)
    quarta-feira, 22 de agosto de 2012 14:20
  • Resolvido então?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quarta-feira, 22 de agosto de 2012 15:03
    Moderador
  • Penso que sim...tenho de rever tudo..
    quarta-feira, 22 de agosto de 2012 15:27
  • Olá amigo. Conseguiu rever?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quinta-feira, 23 de agosto de 2012 03:10
    Moderador
  • como posso solucionar o facto de acontecer mais do que um registo em cada dia. Atribuir apenas o numero de dias ao registo mais recente?
    quinta-feira, 23 de agosto de 2012 08:59
  • Qual a versão do seu SQL?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quinta-feira, 23 de agosto de 2012 17:12
    Moderador
  • 2012 bi
    quinta-feira, 23 de agosto de 2012 17:26
  • Então dá pra você usar CTE.

    Vou postar um exemplo que possui o cenário que você mencionou. Dê uma estudada neste script e veja como adaptá-lo à sua situação.

    Obs.: Não esqueça por favor de votar em todas as respostas que já lhe foram úteis nesta Thread. Abs.

    Create Table #Teste
    (
      STAMP int Identity,
      NUMERO int,
      CONSUMIDOR Char(01),
      DATA DateTime
    )
    
    Insert Into #Teste Values
    (10, 'A', '08/20/2012'), (10, 'A', '08/20/2012'), (10, 'A', '08/21/2012'), (10, 'A', '08/22/2012'),
    (20, 'B', '08/24/2012'), (20, 'B', '08/24/2012'), (20, 'C', '08/25/2012'), (20, 'C', '08/26/2012'),
    (20, 'C', '08/30/2012'), (20, 'C', '08/30/2012')
    
    ;With CTE as
    (
     SELECT
       T1.STAMP,
       T1.NUMERO,
       T1.CONSUMIDOR,
       T1.DATA,
       NrDiasDiferenca = IsNull(DateDiff(dd, T2.DATA, T1.DATA), 0)
     From
       (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
        From #Teste) T1 LEFT JOIN
       (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by Data)
        From #Teste) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                           (T2.NUMERO     = T1.NUMERO)      and
                           (T2.CONSUMIDOR = T1.CONSUMIDOR)
     )
    Select
      T.*,
      NrDiasDiferencaFinal = IsNull(C.NrDiasDiferenca, 0)
    From
      #Teste T Left Join (Select * From CTE Where (NrDiasDiferenca > 0)) C on (T.NUMERO     = C.NUMERO)     and
                                                                              (T.CONSUMIDOR = C.CONSUMIDOR) and
    																  	      (T.DATA       = C.DATA)
    Order by
       T.NUMERO,
       T.CONSUMIDOR,
       T.DATA
    
    Drop Table #Teste


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quinta-feira, 23 de agosto de 2012 18:02
    Moderador
  • O que faz isso?
    sexta-feira, 24 de agosto de 2012 10:12
  • Eu apenas quero alterar esta subquery de forma a que adicione apenas o registo, no mais recente do dia.

    (SELECT TOP 1 DATEDIFF(dd,A.DATA,B.DATA)

    FROM TABELA AS A (NOLOCK) 

    WHERE ((A.NUMEROCONSUMIDOR = B.NUMEROCONSUMIDOR)

    AND (A.DATA+A.HORA <= B.DATA+B.HORA)

    AND (A.STAMP <> B.STAMP))

    ORDER BY A.DATA+A.HORA),0) AS 'DIAS_ENTRE_DATAS' 


    Quando ocorre mais do que um registo no dia, eu pretendo apenas que insira num único registo, como está acontecendo, mas que seja no registo mais recente. Pretendo alterar a subquery acima


    sexta-feira, 24 de agosto de 2012 10:32
  • Você tem uma coluna Data e uma coluna Hora, separadamente. Qual o tipo de dados de cada uma?

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 24 de agosto de 2012 10:52
    Moderador
  • data = datetime

    hora = time

    data+hora= datetime - A.DATA+A.HORA

    sexta-feira, 24 de agosto de 2012 13:01
  • No exemplo que eu tinha lhe dado, em vez de ordenar por data + hora na cláusula Over do Row_Number, ordene por Data, Hora desc.

    Exemplo:

    Drop Table #Teste
    
    Create Table #Teste
    (
      STAMP int Identity,
      NUMERO int,
      CONSUMIDOR Char(01),
      DATA DateTime,
      HORA Time
    )
    
    Insert Into #Teste Values
    (10, 'A', '08/20/2012', '10:00'), (10, 'A', '08/21/2012', '10:05'), (10, 'A', '08/21/2012', '10:07'), (10, 'A', '08/22/2012', '10:10'),
    (20, 'B', '08/24/2012', '11:20'), (20, 'B', '08/25/2012', '11:10'), (20, 'B', '08/25/2012', '11:15'), (20, 'C', '08/26/2012', '11:10'),
    (20, 'C', '08/30/2012', '12:15'), (20, 'C', '08/30/2012', '12:10'), (20, 'C', '08/30/2012', '12:20')
    
    SELECT
       T1.STAMP,
       T1.NUMERO,
       T1.CONSUMIDOR,
       T1.DATA,
       T1.HORA,
       NrDiasDiferenca = IsNull(DateDiff(dd, T2.DATA, T1.DATA), 0)
     From
       (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by DATA, HORA desc)
        From #Teste) T1 LEFT JOIN
       (Select *, IdLinha = ROW_NUMBER() Over (Partition by NUMERO, CONSUMIDOR Order by DATA, HORA desc)
        From #Teste) T2 ON (T2.IdLinha    = T1.IdLinha - 1) and
                           (T2.NUMERO     = T1.NUMERO)      and
                           (T2.CONSUMIDOR = T1.CONSUMIDOR)
    ORDER BY
      T1.NUMERO,
      T1.CONSUMIDOR,
      T1.DATA


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 24 de agosto de 2012 13:10
    Moderador
  • ja está, mas nao está funcionando... ele insere apenas num aleatorio, e nao no mais recente.
    sexta-feira, 24 de agosto de 2012 13:26
  • Posta o código atual que está usando.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 24 de agosto de 2012 13:29
    Moderador
  • (SELECT TOP 1 DATEDIFF(dd,A.DATA,B.DATA) 

    FROM TABELA AS A (NOLOCK) 

    WHERE ((A.NUMEROCONSUMIDOR = B.NUMEROCONSUMIDOR) AND (A.DATA+A.HORA <= B.DATA+B.HORA) AND (A.STAMP <> B.STAMP))

    ORDER BY A.DATA+A.HORA DESC),0) AS 'DIAS_ENTRE_DATAS' 


    sexta-feira, 24 de agosto de 2012 13:39
  • Bem, cara, duas situações:

    1) Seu Order by não está como eu falei: Data, Hora desc. Ele está Data + Hora.

    2) Mesmo colocando Data, Horas desc não dá pra dizer que vai funcionar, pois seu código está conceitualmente diferente do exemplo com Row_Number que venho postando. É possível que só consiga atingir seu objetivo se conseguir utilizar o Row_Number() Over() em sua sintaxe.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta sql-enthusiast sexta-feira, 24 de agosto de 2012 13:59
    sexta-feira, 24 de agosto de 2012 13:49
    Moderador
  • Bem, cara, duas situações:

    1) Seu Order by não está como eu falei: Data, Hora desc. Ele está Data + Hora.

    2) Mesmo colocando Data, Horas desc não dá pra dizer que vai funcionar, pois seu código está conceitualmente diferente do exemplo com Row_Number que venho postando. É possível que só consiga atingir seu objetivo se conseguir utilizar o Row_Number() Over() em sua sintaxe.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    ok eu vou dar uma olhada nisso, depois eu digo se deu ou nao mais logo.
    sexta-feira, 24 de agosto de 2012 13:59
  • ja agora qual a diferença entre ter a data, hora ou data+hora?
    sexta-feira, 24 de agosto de 2012 14:00
  • Como a ordenação é decrescente, Data, Hora desc faz com que somente a Hora seja ordenada decrescentemente.

    Data + Hora desc ordenará a concatenação de forma decrescente.

    Melhor explicar com um exemplo. Veja a diferença entre os resultados dos Selects:

    Create Table #Tabela (Codigo int, Data DateTime, Hora Time)
    Insert Into #Tabela Values (1, '08/23/2012', '10:00'), (2, '08/23/2012', '10:05'),
    (3, '08/24/2012', '12:40'), (4, '08/24/2012', '12:35')
    
    Select * From #Tabela Order by Data + Hora desc
    Select * From #Tabela Order by Data, Hora desc


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 24 de agosto de 2012 14:14
    Moderador