Problema:
Tienes dos columnas del tipo datetime
y quieres calcular la diferencia entre ellos.
Ejemplo:
En el travel
tabla, hay tres columnas:id
, departure
y arrival
. Le gustaría calcular la diferencia entre la arrival
y la departure
.
El travel
la tabla se ve así:
id | salida | llegada |
---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 |
2 | 2019-09-12 15:50:00 | 2019-10-23 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 |
Solución 1 (diferencia en segundos):
SELECT id, departure, arrival, DATEDIFF(second, departure, arrival) AS difference FROM travel;
El resultado es:
id | salida | llegada | diferencia |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 934200 |
2 | 2019-09-12 15:50:00 | 2019-10-23 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 |
Discusión:
Para calcular la diferencia entre la arrival
y la salida en T-SQL, use DATEDIFF(datepart, startdate, enddate)
función. El datepart
el argumento puede ser microsecond
, second
, minute
, hour
, day
, week
, month
, quarter
, o year
. Aquí, le gustaría obtener la diferencia en segundos, así que elija el segundo. Para obtener la diferencia en horas, elija hour
; para la diferencia en meses, elija month
, etc. La startdate
y la enddate
los argumentos son el inicio y el final datetime
columnas, respectivamente (aquí, departure
y arrival
, respectivamente).
Solución 2 (diferencia en días, horas, minutos y segundos):
WITH difference_in_seconds AS ( SELECT id, departure, arrival, DATEDIFF(SECOND, departure, arrival) AS seconds FROM travel ), differences AS ( SELECT id, departure, arrival, seconds, seconds % 60 AS seconds_part, seconds % 3600 AS minutes_part, seconds % (3600 * 24) AS hours_part FROM difference_in_seconds ) SELECT id, departure, arrival, CONCAT( FLOOR(seconds / 3600 / 24), ' days ', FLOOR(hours_part / 3600), ' hours ', FLOOR(minutes_part / 60), ' minutes ', seconds_part, ' seconds' ) AS difference FROM differences;
El resultado es:
id | salida | llegada | diferencia |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 10 días 19 horas 30 minutos 0 segundos |
2 | 2019-09-12 15:50:00 | 2019-10-23 10:30:30 | 40 días 18 horas 40 minutos 30 segundos |
3 | 2018-07-14 16:15:00 | 2018-07-14 20:40:30 | 0 días 4 horas 25 minutos 30 segundos |
4 | 2018-01-05 08:35:00 | 2019-01-08 14:00:00 | 368 días 5 horas 25 minutos 0 segundos |
Discusión:
Primero, calcula la diferencia entre la arrival
y la departure
en segundos, usando DATEDIFF()
función (el primer CTE, denominado difference_in_seconds
), tal como en la Solución 1. Luego, calcule cuántos segundos hay en exceso de los minutos completos (seconds_part
) para ser utilizado posteriormente para calcular los segundos, cuántos segundos hay en exceso de horas enteras (minutes_part
) para ser utilizado más tarde para calcular los minutos y cuántos segundos hay en exceso de las horas enteras (hours_part
) para ser utilizado más tarde para calcular las horas.
Para hacer esto, use el operador %. Por ejemplo, una hora tiene 3600 segundos, así que para saber cuántos segundos hay en minutes_part
, encuentre el resto de la división por 3600 así:
seconds % 3600 AS minutes_part
Del mismo modo, hay 3600 * 24
segundos en un día, para calcular cuántos segundos hay en hours_part
, escribe:
seconds % (3600 * 24) AS hours_part
Una vez calculados estos residuos (en el segundo CTE, denominado differences
), finalmente puede obtener la diferencia en días, horas, minutos y segundos. Para obtener la cantidad de segundos, minutos, horas y días, divida la cantidad de segundos en el resto por la cantidad correspondiente de segundos en días, horas o minutos. Por ejemplo, para averiguar cuántos minutos se deben mostrar, tome minutes_part
y divídalo por 60, ya que hay 60 minutos en una hora. Solo necesita la parte entera de esto (es decir, sin la parte decimal), así que use FLOOR()
funcionar así:
FLOOR(minutes_part / 60)
Finalmente, simplemente necesita mostrar en una cadena lo que ha calculado. Para hacer esto, use CONCAT()
función en la consulta externa:
CONCAT( FLOOR(seconds / 3600 / 24), ' days ', FLOOR(hours_part / 3600), ' hours ', FLOOR(minutes_part / 60), ' minutes ', seconds_part, ' seconds' ) AS difference
La solución presentada aquí devuelve un datetime
diferencia como texto. Puede modificar fácilmente la solución para obtener solo los números sin ningún texto. También puede almacenar días, horas, minutos y segundos en diferentes columnas:
FLOOR(seconds / 3600 / 24) AS days, FLOOR(hours_part / 3600) AS hours, FLOOR(minutes_part / 60) AS minutes, seconds_part AS seconds