W codziennej pracy bardzo często używamy funkcje daty i czasu , które są kluczowe w trakcie przeprowadzania analizy danych czy te tworzenia raportów. Bardzo często spotykamy się z problemem przeliczenia odpowiedniej daty jako początek zadanego okresu czyli początek roku, miesiąca, kwartału itp.
Standardowe wymagania dla zrealizowania tego celu jest użycie dwóch funkcji:
- DateDiff()
- DateAdd()
Obcinamy daty
Pierwszy dzień roku
Najpierw przejdziemy do pierwszego dnia roku. W celu spełnienia tego wymogu, używamy zarówno funkcji DateDiff(), jak i DateAdd().
SELECT DATEADD(year, DATEDIFF(year, 0, '2025-02-14 14:55:01.156'), 0) AS YearStart;
W wyniku dostajemy:
2025-01-01 00:00:00.000
Analogicznie przejdźmy do pierwszego dnia kwartału, miesiąca, pełnego dnia. Dodatkowo użyjmy początek godziny, minuty czy sekundy.
SELECT DATEADD(quarter, DATEDIFF(quarter, 0, '2025-12-24 17:58:26.667'), 0) AS QuarterStart;
SELECT DATEADD(month, DATEDIFF(month, 0, '2025-12-24 17:58:26.667'), 0) AS MonthStart;
SELECT DATEADD(day, DATEDIFF(day, 0, '2025-12-24 17:58:26.667'), 0) AS DayStart;
SELECT DATEADD(hour, DATEDIFF(hour, 0, '2025-12-24 17:58:26.667'), 0) AS HourStart;
SELECT DATEADD(minute, DATEDIFF(minute, 0, '2025-12-24 17:58:26.667'), 0) AS MinuteStart;
Dostajemy analogicznie:
-- QuarterStart
-----------------------
2025-10-01 00:00:00.000
-- MonthStart
-----------------------
2025-12-01 00:00:00.000
-- DayStart
-----------------------
2025-12-24 00:00:00.000
-- HourStart
-----------------------
2025-12-24 17:00:00.000
-- MinuteStart
-----------------------
2025-12-24 17:58:00.000
Zróbmy teraz dla sekund:
--error: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.
select DATEDIFF(second, 0, '2025-12-24 17:58:26.667')
select DATEDIFF_BIG(second, 0, '2025-12-24 17:58:26.667')
--error Arithmetic overflow error converting expression to data type int.
SELECT DATEADD(second, DATEDIFF_BIG(second, 0, '2025-12-24 17:58:26.667'), 0) AS SecondStart;
W tym przypadku dla sekund dostajemy błąd. W przypadku DATEDIFF przekroczyliśmy zakres wartości INT jaką zwraca a funkcja. Musimy wiec użyć DATEDIFF_BIG, która zwraca wartość bigint.
W tym przypadku to zadziałało , ale gdy tą wartość podstawiamy do funkcji DATEADD uzyskamy kolejny błąd ponieważ ta funkcja nie przyjmuje argumentu bigint tylko int.
Co dalej …
W tym momencie z pomocą przychodzi nam funkcja DATETRUNC(), która od SQL Server 2022 pojawiła się do obsługi takich sytuacji.
Funkcja DATETRUNC() pomaga obciąć datę wejściową zgodnie z określoną precyzją. Jego składnia wygląda następująco:
DATETRUNC ( datepart , (input)date ) )
Tutaj datepart może mieć jedną z następujących wartości:
| Obcinajcie do której wartości | datepart |
|---|---|
| Rok | yy, yyyy, rok |
| Ćwierć | qq, q |
| Miesiąc | mm, m |
| Dzień w roku | dy, y |
| Dzień | dd, d |
| Tydzień | WW, WK |
| Iso_week | Isowk, isoww |
| Godzina | Hh |
| Minuta | Mn, n |
| Sekunda | Ss, s |
| milisekundy | Ms |
| Mikrosekundy | mcs |
Poniżej mamy przykłady użycia tej funkcji.
DECLARE @input datetime2 = '2025-12-24 17:58:26.66712345';
SELECT DATETRUNC(YEAR, @input) AS YearStart;
SELECT DATETRUNC(QUARTER, @input) AS QuarterStart;
SELECT DATETRUNC(MONTH, @input) AS MonthStart;
SELECT DATETRUNC(DAY, @input) AS DayStart;
SELECT DATETRUNC(HOUR, @input) AS HourStart;
SELECT DATETRUNC(MINUTE, @input) AS MinuteStart;
SELECT DATETRUNC(SECOND, @input) AS SecondStart;
W rezultacie dostajemy:
YearStart
---------------------------
2025-01-01 00:00:00.0000000
QuarterStart
---------------------------
2025-10-01 00:00:00.0000000
MonthStart
---------------------------
2025-12-01 00:00:00.0000000
DayStart
---------------------------
2025-12-24 00:00:00.0000000
HourStart
---------------------------
2025-12-24 17:00:00.0000000
MinuteStart
---------------------------
2025-12-24 17:58:00.0000000
SecondStart
---------------------------
2025-12-24 17:58:26.0000000
Jak widać przy wyliczeniu sekund nie powstaje błąd.