Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como calcular a diferença entre dois timestamps no MySQL

Problema:


Você tem duas colunas do tipo timestamp e deseja calcular a diferença entre elas.

Exemplo:


Na travel tabela, há três colunas:id , departure , e arrival . Você gostaria de calcular a diferença entre a arrival e a departure .

A travel tabela fica assim:
id partida chegada
1 2018-03-25 12:00:00 2018-04-05 07:30:00
2 2019-09-12 15:50:00 23/10/2019 10:30:30
3 2018-07-14 16:15:00 2018-07-14 20:40:30
4 2018-01-05 08:35:00 2019-01-08 14:00:00

Solução 1 (diferença em dias, horas, minutos ou segundos):

SELECT id, partida, chegada, TIMESTAMPDIFF(SECOND, partida, chegada) AS diferençaFROM viagem;

O resultado é:
id partida chegada diferença
1 2018-03-25 12:00:00 2018-04-05 07:30:00 934200
2 2019-09-12 15:50:00 23/10/2019 10:30:30 3523230
3 2018-07-14 16:15:00 2018-07-14 20:40:30 15930
4 2018-01-05 08:35:00 2019-01-08 14:00:00 31814700

Discussão:


Para calcular a diferença entre os timestamps no MySQL, use o TIMESTAMPDIFF(unit, start, end) função. O argumento da unidade pode ser MICROSECOND , SECOND , MINUTE , HOUR , DAY , WEEK , MONTH , QUARTER , ou YEAR . Para obter a diferença em segundos como fizemos aqui, escolha SECOND . Para obter a diferença em minutos, escolha MINUTE; para a diferença em horas, escolha HOUR , etc. Os argumentos end e start são o timestamp final e o timestamp inicial, respectivamente (aqui, departure e arrival , respectively ).

Solução 2 (diferença em dias, horas, minutos e segundos):

WITH Difference_in_seconds AS ( SELECT id, partida, chegada, TIMESTAMPDIFF(SECOND, partida, chegada) AS segundos da viagem),diferenças AS (SELECT id, partida, chegada, segundos, MOD(segundos, 60) AS segundos_parte, MOD (segundos, 3600) AS minutos_parte, MOD(segundos, 3600 * 24) AS horas_parte FROM diferença_em_segundos)SELECT id, partida, chegada, CONCAT( FLOOR(segundos / 3600 / 24), 'dias', FLOOR(horas_parte / 3600), ' horas ', FLOOR(minutos_parte / 60), 'minutos', segundos_parte, 'segundos' ) AS diferençaFROM diferenças;

O resultado é:
id partida chegada diferença
1 2018-03-25 12:00:00 2018-04-05 07:30:00 10 dias 19 horas 30 minutos 0 segundos
2 2019-09-12 15:50:00 23/10/2019 10:30:30 40 dias 18 horas 40 minutos e 30 segundos
3 2018-07-14 16:15:00 2018-07-14 20:40:30 0 dias 4 horas 25 minutos 30 segundos
4 2018-01-05 08:35:00 2019-01-08 14:00:00 368 dias 5 horas 25 minutos 0 segundos

Discussão:


Primeiro, calcule a diferença entre os timestamps em segundos, usando o TIMESTAMPDIFF() função (o primeiro CTE, chamado difference_in_seconds ), assim como na Solução 1. Calcule quantos segundos existem além dos minutos inteiros (seconds_part ) para ser usado posteriormente para calcular os segundos, quantos segundos existem em excesso de horas inteiras (minutes_part ) para ser usado posteriormente para calcular os minutos e quantos segundos existem além das horas inteiras (hours_part ) para ser usado posteriormente para calcular as horas.

Para fazer isso, use o MOD() função. Por exemplo, uma hora tem 3600 segundos, então para descobrir quantos segundos existem em minutes_part , encontre o resto da divisão por 3600 assim:

MOD(seconds, 3600) AS minutes_part

Da mesma forma, existem 3600 * 24 segundos em um dia, para calcular quantos segundos existem em hours_part , escrever:

MOD(seconds, 3600 * 24) AS hours_part

Uma vez que esses restos são calculados (no segundo CTE, chamado differences ), você pode finalmente obter a diferença em dias, horas, minutos e segundos. Para obter o número de segundos, minutos, horas e dias, divida o número de segundos no restante pelo número correspondente de segundos em dias, horas ou minutos. Por exemplo, para descobrir quantos minutos devem ser exibidos, use minutes_part e divida-o por 60, pois há 60 minutos em uma hora. Você só precisa da parte inteira disso (ou seja, sem a parte decimal), então use a função FLOOR() assim:

FLOOR(minutes_part / 60)

Finalmente, você só precisa exibir em uma string o que você calculou. Para fazer isso, use o CONCAT() função na consulta externa:
CONCAT( FLOOR(seconds / 3600 / 24), ' days ', FLOOR(hours_part / 3600), ' hours ', FLOOR(minutes_part / 60), ' minutes ', seconds_part, 'seconds' ) AS diferença 
A solução apresentada aqui retorna a última coluna como texto. Você pode modificar facilmente esta solução para exibi-la em algum outro formato. Você também pode exibir os números em colunas separadas, assim:
FLOOR(seconds / 3600 / 24) AS dias,FLOOR(hours_part / 3600) AS horas,FLOOR(minutes_part / 60) AS minutos,seconds_part AS segundos