Database
 sql >> Base de Dados >  >> RDS >> Database

Como calcular a diferença entre dois datetimes em T-SQL

Problema:


Você tem duas colunas do tipo datetime e você deseja calcular a diferença entre eles.

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 segundos):

SELECT id, partida, chegada, DATEDIFF(segundo, partida, chegada) AS diferença da 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 a arrival e a partida em T-SQL, use o DATEDIFF(datepart, startdate, enddate) função. O datepart argumento pode ser microsecond , second , minute , hour , day , week , month , quarter , ou year . Aqui, você gostaria de obter a diferença em segundos, então escolha o segundo. Para obter a diferença em horas, escolha hour; para a diferença em meses, escolha month , etc. A startdate e a enddate os argumentos são o datetime inicial e final colunas, respectivamente (aqui, departure e arrival , respectivamente).

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

WITH Difference_in_seconds AS ( SELECT id, partida, chegada, DATEDIFF(SECOND, partida, chegada) AS segundos da viagem),diferenças AS (SELECT id, partida, chegada, segundos, segundos % 60 AS segundos_parte, segundos % 3600 AS minutos_parte, 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 a arrival e a departure em segundos, usando o DATEDIFF() função (o primeiro CTE, chamado difference_in_seconds ), assim como na Solução 1. Em seguida, 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 operador %. 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:

seconds % 3600 AS minutes_part

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

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 o FLOOR() funcionar 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 um datetime diferença como texto. Você pode modificar facilmente a solução para obter apenas os números sem nenhum texto. Você também pode armazenar dias, horas, minutos e segundos em diferentes colunas:
FLOOR(seconds / 3600 / 24) AS dias,FLOOR(hours_part / 3600) AS horas,FLOOR(minutes_part / 60) AS minutos,seconds_part AS segundos