Problem:
Masz dwie kolumny typu znacznik czasu 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 dniach, godzinach, minutach lub sekundach):
SELECT id, departure, arrival, TIMESTAMPDIFF(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 znacznikami czasu w MySQL, użyj TIMESTAMPDIFF(unit, start, end)
funkcjonować. Argumentem jednostki może być MICROSECOND
, SECOND
, MINUTE
, HOUR
, DAY
, WEEK
, MONTH
, QUARTER
lub YEAR
. Aby uzyskać różnicę w sekundach, tak jak tutaj zrobiliśmy, wybierz SECOND
. Aby uzyskać różnicę w minutach, wybierz MINUTE
; dla różnicy w godzinach wybierz HOUR
, itd. Argumenty end i start to odpowiednio końcowy znacznik czasu i początkowy znacznik czasu (tutaj, departure
i arrival
, respectively
).
Rozwiązanie 2 (różnica w dniach, godzinach, minutach i sekundach):
WITH difference_in_seconds AS ( SELECT id, departure, arrival, TIMESTAMPDIFF(SECOND, departure, arrival) AS seconds FROM travel ), differences AS ( SELECT id, departure, arrival, seconds, MOD(seconds, 60) AS seconds_part, MOD(seconds, 3600) AS minutes_part, MOD(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 znacznikami czasu w sekundach, używając TIMESTAMPDIFF()
funkcja (pierwsze CTE o nazwie difference_in_seconds
), podobnie jak w Rozwiązaniu 1. 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 MOD()
funkcjonować. 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:
MOD(seconds, 3600) AS minutes_part
Podobnie jest 3600 * 24
sekund dziennie, aby obliczyć, ile sekund jest w hours_part
, napisz:
MOD(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 funkcji FLOOR() w następujący sposób:
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 zapytaniu zewnętrznym:
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 ostatnią kolumnę jako tekst. Możesz łatwo zmodyfikować to rozwiązanie, aby wyświetlić je w innym formacie. Możesz także wyświetlić liczby w osobnych kolumnach, tak jak poniżej:
FLOOR(seconds / 3600 / 24) AS days, FLOOR(hours_part / 3600) AS hours, FLOOR(minutes_part / 60) AS minutes, seconds_part AS seconds