Usuário com melhor resposta
Select datediff

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!
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
-
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
-
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
- Editado Lukas de Castro Ruocco Baldan segunda-feira, 25 de junho de 2012 13:08
- Sugerido como Resposta Heloisa Pires terça-feira, 26 de junho de 2012 14:16
- Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
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
-
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
-
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
ENDlembrando 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 !
-
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
-
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
-
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 + 1Já 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.brSe 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. -
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
-
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 !
-
-
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
- Editado Antero Marques sexta-feira, 15 de junho de 2012 21:39
-
-
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
- Editado Lukas de Castro Ruocco Baldan segunda-feira, 25 de junho de 2012 13:08
- Sugerido como Resposta Heloisa Pires terça-feira, 26 de junho de 2012 14:16
- Marcado como Resposta RJ_Silva sexta-feira, 6 de dezembro de 2013 21:55
-