Diferença entra horas

(leandroauler) #1

Galera eu tenho a seguinte query:

select a.*, b.* from
(
SELECT gm.Idaut AS IDIDA, gm.IdGuia AS GIDA,DATE_FORMAT(gm.Data,'%d/%m/%Y') as DATAI, gm.Viagem as ViagensI, gm.Turma as TURMAI, gm.Idcarro as CARROI, gm.IdLinha as LINHAI , gm.Sentido as IDA, DATE_FORMAT(gm.HoraSaida,'%H:%i') as SAIDAI, DATE_FORMAT(gm.HoraChegada,'%H:%i')as CHEGADAI, DATE_FORMAT(gm.Tempo,'%H:%i') as TEMPOI, gm.Passageiros as PAXI FROM guiasmov gm WHERE gm.Data = '2009-09-01' AND gm.Idcarro Between '100' AND '130' AND gm.IdLinha = 13 AND gm.Sentido = 0
)a,
(
SELECT g.Idaut AS IDVOLTA, g.IdGuia as GVOLTA,DATE_FORMAT(g.Data,'%d/%m/%Y') as DATAV, g.Viagem as ViagensV, g.Turma as TURMAV, g.Idcarro as CARROV, g.IdLinha as LINHAV, g.Sentido as VOLTA, DATE_FORMAT(g.HoraSaida,'%H:%i') as SAIDAV, DATE_FORMAT(g.HoraChegada,'%H:%i') as CHEGADAV, DATE_FORMAT(g.Tempo,'%H:%i') as TEMPOV, g.Passageiros as PAXV FROM guiasmov g WHERE g.Data = '2009-09-01' AND g.Idcarro Between '100' AND '130' AND g.IdLinha = 13 AND g.Sentido = 1
)b 
WHERE  b.ViagensV = a.ViagensI and b.TURMAV = a.TURMAI AND b.GVOLTA = a.GIDA
ORDER BY SAIDAI

Que me tras o seguinte resultado

LINHA  VEÍCULO  INTERV PARTIDA CHEGADA TEMPO PASSAG 
 XXXA   44455   00:00   04:55   05:10  00:55   39 
 XXXA   44444   00:00   05:28   06:30  01:02   43
 XXXA   11111   00:00   05:36   06:32  00:56   39 

Queria calcular a o intervalo entre os horarios de partida, que deveria ficar assim:

LINHA  VEÍCULO  INTERV PARTIDA CHEGADA TEMPO PASSAG 
 XXXA   44455   00:00   04:55   05:10  00:55   39 
 XXXA   44444   00:33   05:28   06:30  01:02   43
 XXXA   11111   00:08   05:36   06:32  00:56   39 

Algue tem idéia de como posso fazer isso ?

Abraços,

Leandro

(Diogo Toscano) #2

consulta?

(Haroldo) #3

tente o INTERVAL do sql

(leandroauler) #4

Diogo,

Sim é uma consulta, onde passo os parametros e monto o WHERE …

Mas o problema está fazer a o TIMEDIFF disso…

ele vem listando os registros e teria que fazer esse calculo tipo HoraID 2 - HoraId1, HoraId3 - HoraId2 etc…

(leandroauler) #5

Harold,

O problema está em pegar o registro atual e subtrair do anterior…

COmo citei ao Diogo

(Haroldo) #6

usa sub-select

(leandroauler) #7

Harold,

Como usaria um sub-select para isso…

Tem como me ajudar?

(Haroldo) #8

você de certa forma fez 2 sub-selects no from do select principal.
faça o sub-select retornando a data e hora de saída.
para executar melhor a avaliação precisaria ter a modelagem dos dados (populados) para efetuar testes, pois na teoria tudo funciona, mas na pratica nem sempre…

(leandroauler) #9

Quando chegar em casa te envio

(Diogo Toscano) #10

Como Harold falou … precisaria pegar o registro anterior.

Como tem que ser generico para cada registro … teria que pegar o registro anterior …(se a ordem for pela chave primaria)… so dar um select pegando o registro anterior onde a chave for menor que a atual com limit 0,1 pra trazer apenas 1 registro … espero que de pra entender :-p

se tenho
select codigo, nome from clientes
o registro anterior a esse seria:

select
cli1.codigo,
cli1.nome,
(SELECT cli2.codigo FROM clientes where cli2.codigo < cli1.codigo order by cli2.codigo DESC limit 0,1)
from
clientes
order by
cli1.codigo ASC

juro que fiz de cabeca agora e foi a primeira solucao que me veio(creio que esta correto) … depois o pessoal fala mais sugestao ai …

(leandroauler) #11

Diogo,

Vou testar sua solução e já post se deu certo…

Valeu…

(leandroauler) #12

Diogo

Usando a minha tabela seria mais ou menos isso como você fez acima, mas está dando erro #1241 - Operand should contain 1 column(s)

SELECT
gm.Idaut, 
gm.Data,
gm.Idcarro,
gm.HoraSaida,
gm.Sentido,
(SELECT g.Idaut,g.HoraSaida, timediff(time(g.HoraSaida),time(gm.HoraSaida)) FROM guiasmov g where g.Idaut < gm.Idaut order by g.Idaut DESC  limit 0,1) AS INTERVALOI
FROM guiasmov gm
WHERE
gm.Data = '2009-09-01' AND
gm.Idcarro Between 100 AND 130 AND
gm.Idlinha = 13
AND gm.Sentido = 0
(Diogo Toscano) #13

É pq subselect, para funcionar como 1 campo, deve retornar apenas 1 campo no select.

SELECT timediff(time(g.HoraSaida),time(gm.HoraSaida)) FROM guiasmov g where g.Idaut < gm.Idaut order by g.Idaut DESC limit 0,1

(leandroauler) #14

Diogo,

com esse select

SELECT
gm.Idaut AS ID1,
TIME(gm.HoraSaida) as HORAID1,
(SELECT g.Idaut FROM guiasmov g where g.Idaut < gm.Idaut order by g.Idaut DESC  limit 0,1) AS ID2,
(SELECT TIME(g2.HoraSaida) FROM guiasmov g2 where g2.Idaut = Id2) as HORAID2
FROM guiasmov gm
order by 
gm.Idaut DESC
LIMIT 0,10  
  

Consegui esse resultado, só não consegui o TIMEDIFF

212220;"20:42:00";212219;"20:07:00"
212219;"20:07:00";212218;"19:23:00"
212218;"19:23:00";212217;"18:27:00"
212217;"18:27:00";212216;"16:51:00"
212216;"16:51:00";212215;"16:17:00"
212215;"16:17:00";212214;"15:28:00"
212214;"15:28:00";212213;"14:56:00"
212213;"14:56:00";212212;"14:18:00"
212212;"14:18:00";212211;"13:39:00"
212211;"13:39:00";212210;"12:56:00"
(Haroldo) #15

o timediff funciona direitinho, mas acho que temque passar com a data junto:

SELECT TIMEDIFF(‘2008-12-31 23:59:59.000001’,
-> ‘2008-12-30 01:01:01.000002’);
-> ‘46:58:57.999999’

(leandroauler) #16

Harold,

Tá funcionando direitinho com o TIMEDIFF… porém nem tudo é perfeito…

Os ids não são sequenciais…

Select:

SELECT
gm.Idaut AS IDIDA,
gm.IdGuia AS GIDA, 
DATE_FORMAT(gm.Data,'%d/%m/%Y') as DATAI,
gm.Viagem as ViagensI,
gm.Turma as TURMAI,
gm.Idcarro as CARROI, 
gm.IdLinha as LINHAI , 
gm.Sentido as IDA, 
DATE_FORMAT(gm.HoraSaida,'%H:%i') as SAIDAI, 
DATE_FORMAT(gm.HoraChegada,'%H:%i')as CHEGADAI, 
DATE_FORMAT(gm.Tempo,'%H:%i') as TEMPOI, 
gm.Passageiros as PAXI,
(SELECT gm1.Idaut FROM guiasmov gm1 where gm1.Idaut < gm.Idaut order by gm.Idaut DESC  limit 0,1) AS ID2,
(SELECT TIMEDIFF(DATE_FORMAT(gm.HoraSaida,'%H:%i'),DATE_FORMAT(HoraSaida,'%H:%i')) FROM guiasmov where Idaut = Id2) AS INTERVALOIDA
FROM guiasmov gm 
WHERE
gm.Data = '2009-09-01' AND
gm.Idcarro Between 100 AND 130 AND
gm.Idlinha = 13
AND gm.Sentido = 0
ORDER BY 
SAIDAI
  

Resultado:

"IDIDA""GIDA""DATAI""ViagensI""TURMAI""CARROI""LINHAI""IDA""SAIDAI""CHEGADAI""TEMPOI""PAXI""ID2""INTERVALOIDA"
198495      63413       01/09/2009  1           1       104         13          0           03:58  10:03      06:05   291         198494       -15:32:00          
198731      63457       01/09/2009  1           1       128         13          0           04:08  05:08      01:00   12          198730       -17:27:00          
198620      63432       01/09/2009  1           1       114         13          0           04:30  05:29      00:59   17          198619       -18:19:00          
198581      63425       01/09/2009  1           1       111         13          0           04:32  05:32      01:00   39          198580       -09:12:00          
198705      63453       01/09/2009  1           1       126         13          0           05:21  06:16      00:55   48          198704       -16:55:00          
198485      63411       01/09/2009  1           1       103         13          0           05:41  06:32      00:51   51          198484       -15:18:00          
198733      63457       01/09/2009  2           1       128         13          0           06:01  07:14      01:13   56          198732       00:53:00           
198699      63451       01/09/2009  1           1       125         13          0           06:27  09:20      02:53   194         198698       -09:57:00          

Diogo,
Tem alguma ideia de como fazer usando esse SELECT?
Teria que ser :

198731 - 198495

(Diogo Toscano) #17

O que eu tava falnado era isso aqui:

SELECT gm.Idaut, gm.Data, gm.Idcarro, gm.HoraSaida, gm.Sentido, (SELECT timediff(time(g.HoraSaida),time(gm.HoraSaida)) FROM guiasmov g where g.Idaut < gm.Idaut order by g.Idaut DESC limit 0,1) AS INTERVALOI FROM guiasmov gm WHERE gm.Data = '2009-09-01' AND gm.Idcarro Between 100 AND 130 AND gm.Idlinha = 13 AND gm.Sentido = 0

ou

SELECT gm.Idaut, gm.Data, gm.Idcarro, gm.HoraSaida, gm.Sentido, timediff( (SELECT time(g.HoraSaida) FROM guiasmov g where g.Idaut < gm.Idaut order by g.Idaut DESC limit 0,1 ),time(gm.HoraSaida)) AS INTERVALOI FROM guiasmov gm WHERE gm.Data = '2009-09-01' AND gm.Idcarro Between 100 AND 130 AND gm.Idlinha = 13 AND gm.Sentido = 0

a ideia …

(leandroauler) #18

Diogo,

Como citei acima o problema é que os Ids não são sequenciais…

(leandroauler) #19

Diogo,

Tem alguma idéia para IDS não sequenciais?

(Diogo Toscano) #20

É isso que to dizendo … o que vai importar e muito eh saber a ordem … pois se nao o anterior vai pegar errado.

Qual a ordem que voce quer usar? Mostra o order by original e o interno vai ser ele ao contrario ja que voce quer pegar apenas o primeiro da lista… pra poder fazer o where direito …