Problem:
Du har to kolonner af typen datetime
og du vil beregne forskellen mellem dem.
Eksempel:
I travel
tabel, er der tre kolonner:id
, departure
, og arrival
. Du vil gerne beregne forskellen mellem arrival
og departure
.
travel
tabellen ser sådan ud:
id | afgang | ankomst |
---|---|---|
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 |
Løsning 1 (forskel i sekunder):
VÆLG id, afgang, ankomst, DATODIFF(anden, afgang, ankomst) SOM differenceFROM rejse;
Resultatet er:
id | afgang | ankomst | forskel |
---|---|---|---|
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 |
Diskussion:
For at beregne forskellen mellem arrival
og afgangen i T-SQL, brug DATEDIFF(datepart, startdate, enddate)
fungere. datepart
argument kan være microsecond
, second
, minute
, hour
, day
, week
, month
, quarter
eller year
. Her vil du gerne have forskellen på sekunder, så vælg anden. For at få forskellen i timer skal du vælge hour
; for forskellen i måneder, vælg month
osv. startdate
og enddate
argumenter er start og slutning datetime
kolonner, henholdsvis (her departure
og arrival
, henholdsvis).
Løsning 2 (forskel i dage, timer, minutter og sekunder):
WITH difference_in_seconds AS ( VÆLG id, afgang, ankomst, DATODIFF(SECOND, afgang, ankomst) AS sekunder FRA rejse), forskelle AS ( VÆLG id, afgang, ankomst, sekunder, sekunder % 60 AS sekunder_del, sekunder % 3600 AS minutter_del, sekunder % (3600 * 24) AS timer_del FRA difference_in_seconds)SELECT id, afgang, ankomst, CONCAT( FLOOR(sekunder / 3600 / 24), ' dage ', FLOOR(timer_del / 3600), ' timer ', FLOOR(minutter_del / 60), ' minutter ', sekunder_del, ' sekunder' ) SOM differenceFROM forskelle;
Resultatet er:
id | afgang | ankomst | forskel |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 10 dage 19 timer 30 minutter 0 sekunder |
2 | 2019-09-12 15:50:00 | 2019-10-23 10:30:30 | 40 dage 18 timer 40 minutter 30 sekunder |
3 | 2018-07-14 16:15:00 | 2018-07-14 20:40:30 | 0 dage 4 timer 25 minutter 30 sekunder |
4 | 2018-01-05 08:35:00 | 2019-01-08 14:00:00 | 368 dage 5 timer 25 minutter 0 sekunder |
Diskussion:
Beregn først forskellen mellem arrival
og departure
i sekunder ved at bruge DATEDIFF()
funktion (den første CTE, kaldet difference_in_seconds
), ligesom i løsning 1. Beregn derefter, hvor mange sekunder der er over hele minutter (seconds_part
) bruges senere til at beregne sekunderne, hvor mange sekunder der er over hele timer (minutes_part
) bruges senere til at beregne minutterne, og hvor mange sekunder der er over hele timer (hours_part
) skal bruges senere til at beregne timerne.
For at gøre dette skal du bruge %-operatoren. For eksempel har en time 3600 sekunder, så for at finde ud af, hvor mange sekunder der er i minutes_part
, find resten fra divisionen med 3600 sådan her:
seconds % 3600 AS minutes_part
På samme måde er der 3600 * 24
sekunder på en dag, så for at beregne, hvor mange sekunder der er i hours_part
, skriv:
seconds % (3600 * 24) AS hours_part
Når disse rester er beregnet (i den anden CTE, kaldet differences
), kan du endelig få forskellen i dage, timer, minutter og sekunder. For at få antallet af sekunder, minutter, timer og dage skal du dividere antallet af sekunder i resten med det tilsvarende antal sekunder i dage, timer eller minutter. Tag for eksempel minutes_part
for at finde ud af, hvor mange minutter der skal vises og dividere det med 60, da der er 60 minutter i en time. Du skal kun bruge heltalsdelen fra denne (dvs. uden decimaldelen), så brug FLOOR()
fungerer sådan her:
FLOOR(minutes_part / 60)
Til sidst skal du blot vise i én streng, hvad du har beregnet. For at gøre dette skal du bruge CONCAT()
funktion i den ydre forespørgsel:
CONCAT( FLOOR(sekunder / 3600 / 24), ' dage ', FLOOR(timer_del / 3600), ' timer ', FLOOR(minutter_del / 60), ' minutter ', sekunder_del, ' sekunder' ) AS forskelLøsningen præsenteret her returnerer en
datetime
forskel som tekst. Du kan nemt ændre løsningen til kun at få tallene uden nogen tekst. Du kan også gemme dage, timer, minutter og sekunder i forskellige kolonner:FLOOR(sekunder / 3600 / 24) AS dage,FLOOR(timer_del / 3600) AS timer,FLOOR(minutter_del / 60) AS minutter,sekunder_del AS sekunder