Problem:
Du har to kolonner af typen tidsstempel, 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 dage, timer, minutter eller sekunder):
SELECT id, departure, arrival, TIMESTAMPDIFF(SECOND, departure, arrival) AS differenceFROM travel;
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 tidsstemplerne i MySQL skal du bruge TIMESTAMPDIFF(unit, start, end)
fungere. Enhedsargumentet kan være MICROSECOND
, SECOND
, MINUTE
, HOUR
, DAY
, WEEK
, MONTH
, QUARTER
eller YEAR
. For at få forskellen på sekunder, som vi har gjort her, skal du vælge SECOND
. For at få forskellen i minutter skal du vælge MINUTE
; for forskellen i timer, vælg HOUR
, osv. Argumenterne for slut og start er henholdsvis sluttidsstemplet og starttidsstemplet (her departure
og arrival
, respectively
).
Løsning 2 (forskel i dage, timer, minutter og sekunder):
WITH difference_in_seconds AS ( VÆLG id, afgang, ankomst, TIMESTAMPDIFF(SECOND, afgang, ankomst) AS sekunder FRA rejse), forskelle AS ( SELECT id, afgang, ankomst, sekunder, MOD(sekunder, 60) AS sekunder_del, MOD (sekunder, 3600) AS minutter_del, MOD(sekunder, 3600 * 24) AS timer_del FRA difference_in_seconds)SELECT id, afgang, ankomst, CONCAT( FLOOR(sekunder / 3600 / 24), ' dage ', FLOOR(timer_del / ), ' 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 tidsstemplerne i sekunder ved hjælp af TIMESTAMPDIFF()
funktion (den første CTE, kaldet difference_in_seconds
), ligesom i løsning 1. Beregn, 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 MOD()
fungere. 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:
MOD(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:
MOD(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()-funktionen som denne:
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 forskelDen her præsenterede løsning returnerer den sidste kolonne som tekst. Du kan nemt ændre denne løsning, så den vises i et andet format. Du kan også vise tallene i separate kolonner, sådan her:
FLOOR(sekunder / 3600 / 24) AS dage,FLOOR(timer_del / 3600) AS timer,FLOOR(minutter_del / 60) AS minutter,sekunder_del AS sekunder