Problem:
Du har två kolumner av typen datetime
och du vill beräkna skillnaden mellan dem.
Exempel:
I travel
tabell, det finns tre kolumner:id
, departure
och arrival
. Du vill beräkna skillnaden mellan arrival
och departure
.
travel
tabellen ser ut så här:
id | avgång | 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 (skillnad i sekunder):
VÄLJ ID, avgång, ankomst, DATUMDIFF(andra, avgång, ankomst) SOM skillnad FROM resa;
Resultatet är:
id | avgång | ankomst | skillnad |
---|---|---|---|
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:
För att beräkna skillnaden mellan arrival
och avgången i T-SQL, använd DATEDIFF(datepart, startdate, enddate)
fungera. datepart
argument kan vara microsecond
, second
, minute
, hour
, day
, week
, month
, quarter
, eller year
. Här vill du få skillnaden på sekunder, så välj tvåa. För att få skillnaden i timmar, välj hour
; för skillnaden i månader, välj month
, etc. startdate
och enddate
argument är början och slutet datetime
kolumner, respektive (här, departure
och arrival
, respektive).
Lösning 2 (skillnad i dagar, timmar, minuter och sekunder):
WITH difference_in_seconds AS ( VÄLJ id, avgång, ankomst, DATUMDIFF(SECOND, avgång, ankomst) AS sekunder FRÅN resa), skillnader AS ( SELECT id, avgång, ankomst, sekunder, sekunder % 60 AS sekunder_del, sekunder % 3600 AS minuter_del, sekunder % (3600 * 24) AS hours_part FROM difference_in_seconds)SELECT id, avgång, ankomst, CONCAT( FLOOR(sekunder / 3600 / 24), ' dagar ', FLOOR(timmar_del / 3600), ' timmar ', FLOOR(minuter_del / 60), 'minuter', seconds_part, ' seconds' ) AS differenceFROM skillnader;
Resultatet är:
id | avgång | ankomst | skillnad |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 10 dagar 19 timmar 30 minuter 0 sekunder |
2 | 2019-09-12 15:50:00 | 2019-10-23 10:30:30 | 40 dagar 18 timmar 40 minuter 30 sekunder |
3 | 2018-07-14 16:15:00 | 2018-07-14 20:40:30 | 0 dagar 4 timmar 25 minuter 30 sekunder |
4 | 2018-01-05 08:35:00 | 2019-01-08 14:00:00 | 368 dagar 5 timmar 25 minuter 0 sekunder |
Diskussion:
Beräkna först skillnaden mellan arrival
och departure
i sekunder, med DATEDIFF()
funktion (den första CTE, som heter difference_in_seconds
), precis som i lösning 1. Beräkna sedan hur många sekunder det finns över hela minuter (seconds_part
) för att användas senare för att beräkna sekunderna, hur många sekunder det finns över hela timmar (minutes_part
) för att användas senare för att beräkna minuterna och hur många sekunder det finns över hela timmar (hours_part
) för att användas senare för att beräkna timmarna.
För att göra detta, använd operatorn %. Till exempel har en timme 3600 sekunder, så för att ta reda på hur många sekunder det finns i minutes_part
, hitta resten från divisionen med 3600 så här:
seconds % 3600 AS minutes_part
På samma sätt finns det 3600 * 24
sekunder på en dag, så för att beräkna hur många sekunder det finns i hours_part
, skriv:
seconds % (3600 * 24) AS hours_part
När dessa rester har beräknats (i den andra CTE, benämnd differences
), kan du äntligen få skillnaden i dagar, timmar, minuter och sekunder. För att få antalet sekunder, minuter, timmar och dagar, dividera antalet sekunder i resten med motsvarande antal sekunder i dagar, timmar eller minuter. Till exempel, för att ta reda på hur många minuter som ska visas, ta minutes_part
och dividera det med 60, eftersom det går 60 minuter på en timme. Du behöver bara heltalsdelen från denna (dvs utan decimaldelen), så använd FLOOR()
fungerar så här:
FLOOR(minutes_part / 60)
Slutligen behöver du bara visa i en sträng vad du har beräknat. För att göra detta, använd CONCAT()
funktion i den yttre frågan:
CONCAT( FLOOR(sekunder / 3600 / 24), ' dagar ', FLOOR(timmar_del / 3600), ' timmar ', FLOOR(minuter_del / 60), ' minuter ', sekunder_del, ' sekunder' ) SOM skillnadLösningen som presenteras här returnerar en
datetime
skillnad som text. Du kan enkelt ändra lösningen för att bara få siffrorna utan någon text. Du kan också lagra dagar, timmar, minuter och sekunder i olika kolumner:FLOOR(seconds / 3600 / 24) AS days,FLOOR(hours_part / 3600) AS hours,FLOOR(minutes_part / 60) AS minutes,seconds_part AS seconds