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