none
Select datediff RRS feed

  • Pergunta

  • Boa Tarde Pessoal !

    Tenho uma tabela com 3 campos

    *MAN_ID =  id da manutencao

    *DT_INICIO = amarzena a data/hora que um determinado evento comeca

    *EVENTO =  o evento que esta sendo feito

    essa tabela serve para amazenar eventos de uma manutencao que esta em andamento e preciso informar o horario que inicia o evento mas devido a minha regra de negorcio nao posso criar o campo "DT_FIM", para mim saber quanto tempo cada evento demorou

    o fim de um evento e justamente o inicio do proximo,

    Entao preciso criar um select que me informa a diferenca de tempo em horas entre o DT_INICIO de um registro e o ultimo DT_INICIO do proximo registro.

    Se eu tivesse o DT_FIM faria um datediff entre os dois mas como nao posso ter o campo DT_FIM teria como eu fazer da forma citada acima ?

    Agradeco a atencao de todos!

    quarta-feira, 13 de junho de 2012 17:40

Respostas

  • Olá Rafael,

    bem segue uma idéia

    CREATE TABLE #TESTE(
    MAN_ID INT IDENTITY(1,1), 
    DT_INICIO DATETIME,
    EVENTO VARCHAR(50))
    
    INSERT INTO #TESTE
    VALUES ('20120613 12:00:00','EV 1'),
    ('20120613 13:00:00','EV 2'),
    ('20120613 14:30:00','EV 3'),
    ('20120613 16:30:00','EV 4'),
    ('20120613 19:00:00','EV 5')
    
    SELECT A.MAN_ID,A.DT_INICIO,B.DT_INICIO AS DT_FIM, 
    (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.DT_INICIO,A.DT_INICIO) / 60)) + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.DT_INICIO,A.DT_INICIO) % 60) + 100), 2) ) 
    	FROM #TESTE A
    		LEFT JOIN #TESTE B
    			ON A.MAN_ID = B.MAN_ID + 1


    Att.
    Lukas Baldan

    • Sugerido como Resposta Carlos Monteiro sábado, 16 de junho de 2012 19:33
    • Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
    quarta-feira, 13 de junho de 2012 18:48
  • Rafael acho que ficaria mais ou menos assim

    SELECT ...

    FROM MANUTENCAO_ACOMPANHAMENTO AS ACOMP INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON ACOMP.EVE_ID = EVENTO.EVE_ID LEFT JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS PROXIMO_EVENTO ON PROXIMO_EVENTO.EVE_ID = EVENTO.EVE_ID +1



    Att.
    Lukas Baldan

    • Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
    quarta-feira, 13 de junho de 2012 20:33
  • Ola Rafael,

    acredito que com o union você consegue juntar os dois códigos

    SELECT EVENTO.EVE_NOME, A.ACO_DT_INICIO, B.ACO_DT_INICIO AS DT_FIM, (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) / 60)) + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) % 60) + 100), 2) ) FROM MANUTENCAO_ACOMPANHAMENTO A LEFT JOIN MANUTENCAO_ACOMPANHAMENTO B ON (A.ACO_ID = B.ACO_ID + 1) INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON B.EVE_ID = EVENTO.EVE_ID WHERE A.MAN_ID = 62 union

    SELECT * FROM (

    SELECT TOP 1 EVENTO.EVE_NOME, A.ACO_DT_INICIO, A.ACO_DT_INICIO AS DT_FIM, NULL FROM MANUTENCAO_ACOMPANHAMENTO A INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON A.EVE_ID = EVENTO.EVE_ID WHERE A.MAN_ID = 62 ORDER BY ACO_ID DESC) A

    tente este código tambem veja se tras o mesmo resultado

    SELECT
       EVENTO.EVE_NOME, 
       A.ACO_DT_INICIO,
       B.ACO_DT_INICIO AS DT_FIM, 
          (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) / 60)) 
          + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) % 60) + 100), 2) ) 
     FROM EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO 
    	 inner join MANUTENCAO_ACOMPANHAMENTO  B
    		ON B.EVE_ID = EVENTO.EVE_ID
    	 left join MANUTENCAO_ACOMPANHAMENTO A 
    	  ON (B.ACO_ID = A.ACO_ID -1)
     WHERE A.MAN_ID = 62


    Att.
    Lukas Baldan




    segunda-feira, 25 de junho de 2012 13:00

Todas as Respostas

  • Olá Rafael,

    bem segue uma idéia

    CREATE TABLE #TESTE(
    MAN_ID INT IDENTITY(1,1), 
    DT_INICIO DATETIME,
    EVENTO VARCHAR(50))
    
    INSERT INTO #TESTE
    VALUES ('20120613 12:00:00','EV 1'),
    ('20120613 13:00:00','EV 2'),
    ('20120613 14:30:00','EV 3'),
    ('20120613 16:30:00','EV 4'),
    ('20120613 19:00:00','EV 5')
    
    SELECT A.MAN_ID,A.DT_INICIO,B.DT_INICIO AS DT_FIM, 
    (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.DT_INICIO,A.DT_INICIO) / 60)) + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.DT_INICIO,A.DT_INICIO) % 60) + 100), 2) ) 
    	FROM #TESTE A
    		LEFT JOIN #TESTE B
    			ON A.MAN_ID = B.MAN_ID + 1


    Att.
    Lukas Baldan

    • Sugerido como Resposta Carlos Monteiro sábado, 16 de junho de 2012 19:33
    • Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
    quarta-feira, 13 de junho de 2012 18:48
  • Perfeito Baldan,

    só trocaria a linha de conversão por

    ...

    CONVERT(varchar(12), DATEADD(ms, DATEDIFF(ms, B.DT_INICIO, A.DT_INICIO), 0), 114) 

    ....


    Antero Marques

    • Sugerido como Resposta Carlos Monteiro sábado, 16 de junho de 2012 19:31
    quarta-feira, 13 de junho de 2012 19:27
  • Obrigado Lukas por responder, 

    Sua ideia é exatamente o que preciso mas nao estou conseguindo aplicar no meu projeto poderia me dar uma forca? tentei fazer aqui mas no campo DT_FIM e on mostraria a hora ficou NULL no seu exmplo mostro perfeitamente mas no meu nao.

    ai segue a stored procedure que estou tentando fazer se puder me dar uma ideia agradeco.

     procedure [dbo].[GRIDVIEW_ACOMPANHAMENTO_MANUTENCAO]
    @MANUTENCAO_ID int

    AS
    BEGIN 

    SELECT  ACOMP.*,EVENTO.* FROM MANUTENCAO_ACOMPANHAMENTO AS ACOMP
    INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON ACOMP.EVE_ID = EVENTO.EVE_ID
     
     
    WHERE  MAN_ID  LIKE @MANUTENCAO_ID
    END

      

    lembrando que MAN_ID é o id do manutencao e ACO_ID seria o id da tabela acomanhamento_manutencao.... os eventos estao em outra tabela por isso o inner join no codigo acima 

    Obrigado pela sua atencao !

    quarta-feira, 13 de junho de 2012 20:30
  • Rafael acho que ficaria mais ou menos assim

    SELECT ...

    FROM MANUTENCAO_ACOMPANHAMENTO AS ACOMP INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON ACOMP.EVE_ID = EVENTO.EVE_ID LEFT JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS PROXIMO_EVENTO ON PROXIMO_EVENTO.EVE_ID = EVENTO.EVE_ID +1



    Att.
    Lukas Baldan

    • Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
    quarta-feira, 13 de junho de 2012 20:33
  • Desculpa em insistir Lukas mas consegui com o codigo abaixo mas o problema eh que a primeira linha nao traz as informacoes da tabela EVENTO apartir da segunda linha fica tudo normal 

     SELECT EVENTO.*, A.MAN_ID,A.ACO_DT_INICIO,B.ACO_DT_INICIO AS DT_FIM, 
    (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) / 60)) + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) % 60) + 100), 2) ) 
    FROM MANUTENCAO_ACOMPANHAMENTO A
    LEFT JOIN MANUTENCAO_ACOMPANHAMENTO  B
    INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON B.EVE_ID = EVENTO.EVE_ID
    ON A.ACO_ID = B.ACO_ID + 1

    Sabe me dizer como resolver?

    Obrigado

    quarta-feira, 13 de junho de 2012 22:08
  • Rafael, não vou entrar muito em detalhes, mas me chamou a atenção a seguinte parte de sua construção:

    FROM MANUTENCAO_ACOMPANHAMENTO A
    LEFT JOIN MANUTENCAO_ACOMPANHAMENTO  B
    INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON B.EVE_ID = EVENTO.EVE_ID
    ON A.ACO_ID = B.ACO_ID + 1

    Já tentou da forma abaixo?

    FROM MANUTENCAO_ACOMPANHAMENTO A LEFT JOIN MANUTENCAO_ACOMPANHAMENTO  B ON (A.ACO_ID = B.ACO_ID + 1)
    INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON B.EVE_ID = EVENTO.EVE_ID




    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, 14 de junho de 2012 02:22
    Moderador
  • Rafael,

    Acho que houve um pouco de confusão aqui. Na resposta com print que você retornou, percebi que não era só o problema da informação faltante, mas as informações estavam totalmente desconexas.

    De acordo com tuas informações, para cada manutenção há um ou mais eventos. Pois bem, as datas são referentes ao começo de um evento e não da manutenção, a não ser a do primeiro evento que evidencia o começo da manutenção.

    Então, a tabela base para tua seleção deve ser a tabela de eventos de onde você referenciará a tabela de manutenção por 2 vezes obtendo a data inicial do evento e a data do próximo evento.

    No caso, estamos supondo que o evento obtém código sequencial sem furos.

    Veja o exemplo a seguir:

    DECLARE @MANUTENCAO_ACOMPANHAMENTO TABLE 
      ( 
         man_id        INT, 
         eve_id        INT, 
         aco_dt_inicio DATETIME 
      ) 
    DECLARE @EVENTO_MANUTENCAO_ACOMPANHAMENTO TABLE 
      ( 
         eve_id   INT IDENTITY(1, 1), 
         eve_nome VARCHAR(30) 
      ) 

    INSERT INTO @EVENTO_MANUTENCAO_ACOMPANHAMENTO 
                (eve_nome) 
    SELECT 'AG. MATERIAL' 

    INSERT INTO @EVENTO_MANUTENCAO_ACOMPANHAMENTO 
                (eve_nome) 
    SELECT 'AG. PROGR. COMPONENTES' 

    INSERT INTO @EVENTO_MANUTENCAO_ACOMPANHAMENTO 
                (eve_nome) 
    SELECT 'AG. INTERNO' 

    INSERT INTO @EVENTO_MANUTENCAO_ACOMPANHAMENTO 
                (eve_nome) 
    SELECT 'AG. TESTE 1' 

    INSERT INTO @EVENTO_MANUTENCAO_ACOMPANHAMENTO 
                (eve_nome) 
    SELECT 'AG. TESTE 2' 

    INSERT INTO @MANUTENCAO_ACOMPANHAMENTO 
                (man_id, 
                 eve_id, 
                 aco_dt_inicio) 
    SELECT 1, 
           1, 
           '2012-01-01 08:00' 

    INSERT INTO @MANUTENCAO_ACOMPANHAMENTO 
                (man_id, 
                 eve_id, 
                 aco_dt_inicio) 
    SELECT 1, 
           2, 
           '2012-01-01 12:32' 

    INSERT INTO @MANUTENCAO_ACOMPANHAMENTO 
                (man_id, 
                 eve_id, 
                 aco_dt_inicio) 
    SELECT 1, 
           3, 
           '2012-01-01 15:45' 

    INSERT INTO @MANUTENCAO_ACOMPANHAMENTO 
                (man_id, 
                 eve_id, 
                 aco_dt_inicio) 
    SELECT 1, 
           4, 
           '2012-01-01 17:56' 

    INSERT INTO @MANUTENCAO_ACOMPANHAMENTO 
                (man_id, 
                 eve_id, 
                 aco_dt_inicio) 
    SELECT 1, 
           5, 
           '2012-01-01 22:34' 

    SELECT E.*, A.man_id, A.aco_dt_inicio DT_INICIO, B.aco_dt_inicio DT_FIM, 
           CONVERT(VARCHAR(12), Dateadd(ms, Datediff(ms, A.aco_dt_inicio, B.aco_dt_inicio)0), 114) TEMPO
    FROM   @EVENTO_MANUTENCAO_ACOMPANHAMENTO E 
           LEFT JOIN @MANUTENCAO_ACOMPANHAMENTO A 
                   ON E.eve_id = A.eve_id 
           LEFT JOIN @MANUTENCAO_ACOMPANHAMENTO B 
                   ON E.eve_id + 1 = B.eve_id 

    -----------------------------------------------------------------------

    Note que a última linha está com valor nulo para data final e tempo, pois não existe o próximo evento.



    Antero Marques

    quinta-feira, 14 de junho de 2012 03:44
  • Pessoal desculpa voltar nesse topico mas realmente nao estou conseguindo resolver ...nao tenho muita experiencia em SQL .e tbm talvez eu nao soube explicar certinho o meu problemas 

    mas vlw pela atencao e se puder darem uma ollhada pq da forma que eu conseguir fazer esta pulando a primeira linha .

    Segue o link com as tres tabelas se alguem puder dar uma olhada ! 

    http://www.4shared.com/rar/jmgM1RpN/TESTE.html

    Agradeco !

    quinta-feira, 14 de junho de 2012 22:48
  • Alguem pode me dar forca ai por favor !

    Obrigado !

    sexta-feira, 15 de junho de 2012 20:21
  • Podemos sim Rafael,

    Mas não tenho ambiente de mesma versão para fazer testes aqui.

    Mas se você passar as estruturas das tabelas envolvidas já basta. Confirme se o que disse na minha última avaliação está correto.


    Antero Marques


    sexta-feira, 15 de junho de 2012 21:38
  • Junior,

    Pela estrutura que você passou no txt, a resposta que te dei com o código é o que você precisa. Especifique sua dificuldade. Aguardo.


    Antero Marques

    sábado, 16 de junho de 2012 02:36
  • Ola Rafael,

    acredito que com o union você consegue juntar os dois códigos

    SELECT EVENTO.EVE_NOME, A.ACO_DT_INICIO, B.ACO_DT_INICIO AS DT_FIM, (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) / 60)) + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) % 60) + 100), 2) ) FROM MANUTENCAO_ACOMPANHAMENTO A LEFT JOIN MANUTENCAO_ACOMPANHAMENTO B ON (A.ACO_ID = B.ACO_ID + 1) INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON B.EVE_ID = EVENTO.EVE_ID WHERE A.MAN_ID = 62 union

    SELECT * FROM (

    SELECT TOP 1 EVENTO.EVE_NOME, A.ACO_DT_INICIO, A.ACO_DT_INICIO AS DT_FIM, NULL FROM MANUTENCAO_ACOMPANHAMENTO A INNER JOIN EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO ON A.EVE_ID = EVENTO.EVE_ID WHERE A.MAN_ID = 62 ORDER BY ACO_ID DESC) A

    tente este código tambem veja se tras o mesmo resultado

    SELECT
       EVENTO.EVE_NOME, 
       A.ACO_DT_INICIO,
       B.ACO_DT_INICIO AS DT_FIM, 
          (CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) / 60)) 
          + ':' + RIGHT(CONVERT(VARCHAR, CONVERT(int, DATEDIFF(MINUTE,B.ACO_DT_INICIO,A.ACO_DT_INICIO) % 60) + 100), 2) ) 
     FROM EVENTO_ACOMPANHAMENTO_MANUTENCAO AS EVENTO 
    	 inner join MANUTENCAO_ACOMPANHAMENTO  B
    		ON B.EVE_ID = EVENTO.EVE_ID
    	 left join MANUTENCAO_ACOMPANHAMENTO A 
    	  ON (B.ACO_ID = A.ACO_ID -1)
     WHERE A.MAN_ID = 62


    Att.
    Lukas Baldan




    segunda-feira, 25 de junho de 2012 13:00
  • Olá Rafael,

    Pelo que vi aqui a imagem do primeiro exemplo está igual,

    Acredito que essa diferença dos campos ocorre pela ordem do select e não pelo union.


    Att.
    Lukas Baldan

    quarta-feira, 27 de junho de 2012 11:13