sql >> Base de Datos >  >> RDS >> Mysql

Cómo calcular la diferencia entre dos marcas de tiempo en MySQL

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