Problema:
Hai due colonne del tipo datetime
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 secondi):
SELECT id, departure, arrival, DATEDIFF(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 l'arrival
e la partenza in T-SQL, usa il DATEDIFF(datepart, startdate, enddate)
funzione. Il datepart
l'argomento può essere microsecond
, second
, minute
, hour
, day
, week
, month
, quarter
o year
. Qui, vorresti ottenere la differenza in secondi, quindi scegli il secondo. Per ottenere la differenza in ore, scegli hour
; per la differenza in mesi, scegli month
, ecc. La startdate
e il enddate
gli argomenti sono l'inizio e la fine datetime
colonne, rispettivamente (qui, departure
e arrival
, rispettivamente).
Soluzione 2 (differenza in giorni, ore, minuti e secondi):
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;
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 l'arrival
e la departure
in pochi secondi, utilizzando il DATEDIFF()
funzione (il primo CTE, denominato difference_in_seconds
), proprio come nella Soluzione 1. Quindi, calcola quanti secondi ci sono in più rispetto ai 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.
A tale scopo, utilizzare l'operatore %. 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:
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:
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 il FLOOR()
funziona 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 un datetime
differenza come testo. Puoi facilmente modificare la soluzione per ottenere solo i numeri senza testo. Puoi anche memorizzare giorni, ore, minuti e secondi in diverse colonne:
FLOOR(seconds / 3600 / 24) AS days, FLOOR(hours_part / 3600) AS hours, FLOOR(minutes_part / 60) AS minutes, seconds_part AS seconds