Mysql
 sql >> Database >  >> RDS >> Mysql

Come calcolare la differenza tra due timestamp in MySQL

Problema:

Hai due colonne del tipo timestamp e vuoi calcolare la differenza tra loro.

Esempio:

Nel travel tabella, ci sono tre colonne:id , departure e arrival . Vorresti calcolare la differenza tra l'arrival e la departure .

Il travel la tabella si presenta così:

id partenza arrivo
1 25-03-2018 12:00:00 2018-04-05 07:30:00
2 12-09-2019 15:50:00 23-10-2019 10:30:30
3 14-07-2018 16:15:00 2018-07-14 20:40:30
4 05-01-2018 08:35:00 08-01-2019 14:00:00

Soluzione 1 (differenza in giorni, ore, minuti o secondi):

SELECT
  id,
  departure,
  arrival,
  TIMESTAMPDIFF(SECOND, departure, arrival) AS difference
FROM travel;

Il risultato è:

id partenza arrivo differenza
1 25-03-2018 12:00:00 2018-04-05 07:30:00 934200
2 12-09-2019 15:50:00 23-10-2019 10:30:30 3523230
3 14-07-2018 16:15:00 2018-07-14 20:40:30 15930
4 05-01-2018 08:35:00 08-01-2019 14:00:00 31814700

Discussione:

Per calcolare la differenza tra i timestamp in MySQL, usa TIMESTAMPDIFF(unit, start, end) funzione. L'argomento dell'unità può essere MICROSECOND , SECOND , MINUTE , HOUR , DAY , WEEK , MONTH , QUARTER o YEAR . Per ottenere la differenza in secondi come abbiamo fatto qui, scegli SECOND . Per ottenere la differenza in minuti, scegli MINUTE; per la differenza di ore, scegli HOUR , ecc. Gli argomenti end e start sono rispettivamente il timestamp finale e il timestamp iniziale (qui, departure e arrival , respectively ).

Soluzione 2 (differenza in giorni, ore, minuti e secondi):

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;

Il risultato è:

id partenza arrivo differenza
1 25-03-2018 12:00:00 2018-04-05 07:30:00 10 giorni 19 ore 30 minuti 0 secondi
2 12-09-2019 15:50:00 23-10-2019 10:30:30 40 giorni 18 ore 40 minuti 30 secondi
3 14-07-2018 16:15:00 2018-07-14 20:40:30 0 giorni 4 ore 25 minuti 30 secondi
4 05-01-2018 08:35:00 08-01-2019 14:00:00 368 giorni 5 ore 25 minuti 0 secondi

Discussione:

Innanzitutto, calcola la differenza tra i timestamp in secondi, utilizzando TIMESTAMPDIFF() funzione (il primo CTE, denominato difference_in_seconds ), proprio come nella Soluzione 1. Calcola quanti secondi ci sono in più di minuti interi (seconds_part ) da utilizzare successivamente per calcolare i secondi, quanti secondi ci sono in eccesso rispetto alle ore intere (minutes_part ) da utilizzare in seguito per calcolare i minuti, e quanti secondi ci sono in eccesso rispetto alle ore intere (hours_part ) da utilizzare in seguito per calcolare le ore.

Per fare ciò, usa il MOD() funzione. Ad esempio, un'ora ha 3600 secondi, quindi per trovare quanti secondi ci sono in minutes_part , trova il resto della divisione per 3600 in questo modo:

MOD(seconds, 3600) AS minutes_part

Allo stesso modo, ci sono 3600 * 24 secondi in un giorno, quindi per calcolare quanti secondi ci sono in hours_part , scrivi:

MOD(seconds, 3600 * 24) AS hours_part

Una volta calcolati questi resti (nel secondo CTE, denominato differences ), puoi finalmente ottenere la differenza in giorni, ore, minuti e secondi. Per ottenere il numero di secondi, minuti, ore e giorni, dividere il numero di secondi rimanenti per il numero di secondi corrispondente in giorni, ore o minuti. Ad esempio, per scoprire quanti minuti devono essere visualizzati, prendi minutes_part e dividilo per 60, poiché ci sono 60 minuti in un'ora. Hai solo bisogno della parte intera da questo (cioè, senza la parte decimale), quindi usa la funzione FLOOR() in questo modo:

FLOOR(minutes_part / 60)

Infine, devi semplicemente visualizzare in una stringa ciò che hai calcolato. Per fare ciò, usa CONCAT() funzione nella query esterna:

CONCAT(
    FLOOR(seconds / 3600 / 24), ' days ',
    FLOOR(hours_part / 3600), ' hours ',
    FLOOR(minutes_part / 60), ' minutes ',
    seconds_part, ' seconds'
  ) AS difference

La soluzione qui presentata restituisce l'ultima colonna come testo. Puoi facilmente modificare questa soluzione per visualizzarla in un altro formato. Puoi anche visualizzare i numeri in colonne separate, come questa:

FLOOR(seconds / 3600 / 24) AS days,
FLOOR(hours_part / 3600) AS hours,
FLOOR(minutes_part / 60) AS minutes,
seconds_part AS seconds