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