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

Come calcolare la differenza tra due datetime in T-SQL

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