Problema:
Tiene dos columnas del tipo marca de tiempo y desea calcular la diferencia entre ellas.
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 días, horas, minutos o segundos):
SELECT id, departure, arrival, TIMESTAMPDIFF(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 las marcas de tiempo en MySQL, use TIMESTAMPDIFF(unit, start, end)
función. El argumento de la unidad puede ser MICROSECOND
, SECOND
, MINUTE
, HOUR
, DAY
, WEEK
, MONTH
, QUARTER
, o YEAR
. Para obtener la diferencia en segundos como lo hemos hecho aquí, elija SECOND
. Para obtener la diferencia en minutos, seleccione MINUTE
; para la diferencia en horas, elige HOUR
, etc. Los argumentos de inicio y fin son la marca de tiempo final y la marca de tiempo inicial, respectivamente (aquí, departure
y arrival
, respectively
).
Solución 2 (diferencia en días, horas, minutos y segundos):
WITH difference_in_seconds AS ( SELECT id, departure, arrival, TIMESTAMPDIFF(SECOND, departure, arrival) AS seconds FROM travel ), differences AS ( SELECT id, departure, arrival, seconds, MOD(seconds, 60) AS seconds_part, MOD(seconds, 3600) AS minutes_part, MOD(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, calcule la diferencia entre las marcas de tiempo en segundos, usando TIMESTAMPDIFF()
función (el primer CTE, denominado difference_in_seconds
), tal como en la Solución 1. Calcular cuántos segundos hay en exceso de minutos enteros (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 MOD()
función. 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í:
MOD(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:
MOD(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 la función FLOOR() 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 la última columna como texto. Puede modificar fácilmente esta solución para mostrarla en algún otro formato. También puede mostrar los números en columnas separadas, como esta:
FLOOR(seconds / 3600 / 24) AS days, FLOOR(hours_part / 3600) AS hours, FLOOR(minutes_part / 60) AS minutes, seconds_part AS seconds