Problem:
Masz dwie kolumny typu datetime
i chcesz obliczyć różnicę między nimi.
Przykład:
W travel
tabeli, są trzy kolumny:id
, departure
i arrival
. Chcesz obliczyć różnicę między arrival
i departure
.
travel
tabela wygląda tak:
id | wyjazd | przybycie |
---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 |
2 | 2019-09-12 15:50:00 | 23-10-2019 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 |
Rozwiązanie 1 (różnica w sekundach):
SELECT id, departure, arrival, DATEDIFF(second, departure, arrival) AS difference FROM travel;
Wynik:
id | wyjazd | przybycie | różnica |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 934200 |
2 | 2019-09-12 15:50:00 | 23-10-2019 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 |
Dyskusja:
Aby obliczyć różnicę między arrival
i odejście w T-SQL, użyj DATEDIFF(datepart, startdate, enddate)
funkcjonować. datepart
argument może być microsecond
, second
, minute
, hour
, day
, week
, month
, quarter
lub year
. Tutaj chcesz uzyskać różnicę w ciągu kilku sekund, więc wybierz drugą. Aby uzyskać różnicę w godzinach, wybierz hour
; dla różnicy w miesiącach wybierz month
itp. startdate
i enddate
argumentami są początek i koniec datetime
odpowiednio kolumny (tutaj, departure
i arrival
, odpowiednio).
Rozwiązanie 2 (różnica w dniach, godzinach, minutach i sekundach):
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;
Wynik:
id | wyjazd | przybycie | różnica |
---|---|---|---|
1 | 2018-03-25 12:00:00 | 2018-04-05 07:30:00 | 10 dni 19 godzin 30 minut 0 sekund |
2 | 2019-09-12 15:50:00 | 23-10-2019 10:30:30 | 40 dni 18 godzin 40 minut 30 sekund |
3 | 2018-07-14 16:15:00 | 2018-07-14 20:40:30 | 0 dni 4 godziny 25 minut 30 sekund |
4 | 2018-01-05 08:35:00 | 2019-01-08 14:00:00 | 368 dni 5 godzin 25 minut 0 sekund |
Dyskusja:
Najpierw oblicz różnicę między arrival
i departure
w kilka sekund, używając DATEDIFF()
funkcja (pierwsze CTE o nazwie difference_in_seconds
), podobnie jak w Rozwiązaniu 1. Następnie oblicz, ile sekund jest powyżej pełnych minut (seconds_part
) do późniejszego obliczenia sekund, ile sekund przekracza pełne godziny (minutes_part
) do późniejszego obliczenia minut i liczby sekund przekraczających pełne godziny (hours_part
) do wykorzystania później do obliczenia godzin.
Aby to zrobić, użyj operatora %. Na przykład godzina ma 3600 sekund, więc aby dowiedzieć się, ile sekund jest w minutes_part
, znajdź resztę z dzielenia przez 3600 w ten sposób:
seconds % 3600 AS minutes_part
Podobnie jest 3600 * 24
sekund dziennie, aby obliczyć, ile sekund jest w hours_part
, napisz:
seconds % (3600 * 24) AS hours_part
Po obliczeniu tych reszt (w drugim CTE, nazwanym differences
), możesz wreszcie uzyskać różnicę w dniach, godzinach, minutach i sekundach. Aby uzyskać liczbę sekund, minut, godzin i dni, podziel liczbę sekund w pozostałej części przez odpowiednią liczbę sekund w dniach, godzinach lub minutach. Na przykład, aby dowiedzieć się, ile minut powinno być wyświetlane, weź minutes_part
i podziel go przez 60, ponieważ w ciągu godziny jest 60 minut. Potrzebujesz tylko części całkowitej z tego (tzn. bez części dziesiętnej), więc użyj FLOOR()
działać tak:
FLOOR(minutes_part / 60)
Na koniec wystarczy wyświetlić w jednym ciągu to, co obliczyłeś. Aby to zrobić, użyj CONCAT()
funkcja w zewnętrznym zapytaniu:
CONCAT( FLOOR(seconds / 3600 / 24), ' days ', FLOOR(hours_part / 3600), ' hours ', FLOOR(minutes_part / 60), ' minutes ', seconds_part, ' seconds' ) AS difference
Przedstawione tutaj rozwiązanie zwraca datetime
różnica jako tekst. Możesz łatwo zmodyfikować rozwiązanie, aby uzyskać tylko liczby bez tekstu. Możesz także przechowywać dni, godziny, minuty i sekundy w różnych kolumnach:
FLOOR(seconds / 3600 / 24) AS days, FLOOR(hours_part / 3600) AS hours, FLOOR(minutes_part / 60) AS minutes, seconds_part AS seconds