Przejdź do treści
Powrót do Centrum Pomocy
Ilustracja artykułu: Sql server dateadd — kompletny przewodnik 2026
Aplikacje Microsoft

Sql server dateadd — kompletny przewodnik 2026

W tym przewodniku omawiam składnię, typy interwałów (datepart), praktyczne przykłady i optymalizacyjne pułapki, które czekają na programistów SQL w 2026 roku. N

11 min czytania·Zaktualizowano dzisiaj
Autor:Piotr ZielińskiSprawdzone przezKatarzyna NowakAktualizacja: 9 czerwca 2026
Faktura VAT 23% + KSeFDostawa 1-3 min e-mailemGwarancja działania klucza5,0 / 5,0(KluczeSoft)

Funkcja DATEADD w Microsoft SQL Server to jedno z podstawowych narzędzi pracy z datami — pozwala dodawać lub odejmować określone interwały czasu od wskazanej daty. Znajduje zastosowanie w raportowaniu, analityce biznesowej, automatyzacji procesów ETL i budowaniu dynamicznych zapytań SQL.

W tym przewodniku omawiam składnię, typy interwałów (datepart), praktyczne przykłady i optymalizacyjne pułapki, które czekają na programistów SQL w 2026 roku. Niezależnie od tego, czy analizujesz dane w Power BI, tworzysz procedury składowane w aplikacji klasy enterprise, czy przygotowujesz migawkę danych na potrzeby audytu — DATEADD będziesz używać codziennie.

Czym jest funkcja DATEADD — definicja i składnia

DATEADD to wbudowana funkcja T‑SQL, która zwraca nową wartość typu date, datetime, datetime2, datetimeoffset, smalldatetime lub time po dodaniu zadeklarowanego interwału. Sygnatura funkcji wygląda następująco:

DATEADD (datepart, number, date)

Gdzie:

  • datepart — określa jednostkę czasu, którą dodajemy. Może być zapisany w formie pełnej (YEAR, MONTH, DAY) lub skróconej (yy, mm, dd). Microsoft nie ogłosił planów deprecjacji skrótów, jednak w SQL Server 2022 i zapowiedziach dotyczących wersji 2025/2026 rekomenduje pełne nazwy dla czytelności i zgodności z Azure Synapse Analytics oraz Microsoft Fabric.
  • number — liczba całkowita (int) lub wyrażenie zwracające int. Wartości ujemne przesuwają datę wstecz. W SQL Server 2016 i nowszych parametr ten może być także typu bigint dla datepart = NANOSECOND.
  • date — wyrażenie, które może być ewaluowane do jednego z wymienionych wyżej typów daty/czasu. Funkcja nie modyfikuje oryginalnej wartości — zwraca nową.

Przykład najprostszego wywołania:

SELECT DATEADD(DAY, 30, '2026-06-08') AS ZaMiesiac;
-- Wynik: 2026-07-08

Obsługiwane interwały (datepart) — pełna lista 2026

Od SQL Server 2022 w górę lista dostępnych wartości datepart obejmuje jedenaście pozycji. Poniższa tabela przedstawia każdą z nich wraz z typowym przypadkiem użycia:

Interwał (pełna nazwa)SkrótOpis
YEARyy, yyyyDodaje lata
QUARTERqq, qDodaje kwartały
MONTHmm, mDodaje miesiące
DAYOFYEARdy, yDodaje dni roku
DAYdd, dDodaje dni kalendarzowe
WEEKwk, wwDodaje tygodnie
WEEKDAYdw, wDodaje dni robocze (zależne od @@DATEFIRST)
HOURhhDodaje godziny
MINUTEmi, nDodaje minuty
SECONDss, sDodaje sekundy
MILLISECONDmsDodaje milisekundy
MICROSECONDmcsDodaje mikrosekundy
NANOSECONDnsDodaje nanosekundy

Wskazówka 2026: W środowiskach chmurowych Azure SQL Database i Azure SQL Managed Instance (warstwy Hyperscale oraz nowa warstwa „Fabric‑optimized” zapowiedziana na Q2 2026) wartości NANOSECOND mogą być zaokrąglane, ponieważ wewnętrzne znaczniki czasu platformy Azure opierają się na zegarach z dokładnością do 100 ns. Warto to uwzględnić przy migracji obciążeń on‑premises do chmury.

Porównanie DATEADD z DATEDIFF i DATETRUNC

Funkcja DATEADD rzadko występuje w izolacji — najczęściej używa się jej razem z DATEDIFF i, od SQL Server 2022, z DATETRUNC. Znajomość różnic między tymi trzema narzędziami pozwala uniknąć kosztownych błędów w logice biznesowej.

DATEDIFF zwraca liczbę przekroczonych granic interwału pomiędzy dwiema datami. Typowa pułapka: DATEDIFF(YEAR, '2025-12-31', '2026-01-01') zwraca 1, choć minął zaledwie jeden dzień — ponieważ przekroczono granicę roku. Często łączy się DATEDIFF z DATEADD, aby obliczyć początek lub koniec okresu:

-- Początek bieżącego miesiąca
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0);

DATETRUNC (nowość od SQL Server 2022) zaokrągla datę w dół do wskazanej jednostki. Jest czytelniejszą alternatywą dla kombinacji DATEADD/DATEDIFF:

-- Początek bieżącego miesiąca z DATETRUNC
SELECT DATETRUNC(MONTH, GETDATE());

Kiedy w 2026 roku warto zostać przy DATEADD? Głównie wtedy, gdy potrzebujesz precyzyjnego przesunięcia daty („za 45 dni”) zamiast zaokrąglenia. Przy obcinaniu dat DATETRUNC jest zwykle szybszy i bardziej czytelny.

Praktyczne scenariusze biznesowe — 7 przypadków użycia

1. Automatyczne wygasanie ofert i promocji

Platforma e‑commerce zapisuje w kolumnie DataRozpoczecia moment publikacji promocji. Okres trwania oferty (np. 14 dni) jest przechowywany w tabeli konfiguracyjnej:

UPDATE Oferty
SET DataZakonczenia = DATEADD(DAY, 
    (SELECT DniTrwania FROM Konfiguracja WHERE Klucz = 'promocja_dni'),
    DataRozpoczecia)
WHERE Status = 'Aktywna';

2. Automatyczne przedłużanie subskrypcji

W serwisach SaaS subskrypcja miesięczna powinna być przedłużana dokładnie o miesiąc:

UPDATE Subskrypcje
SET DataWaznosci = DATEADD(MONTH, 1, DataWaznosci)
WHERE DataWaznosci = CAST(GETDATE() AS DATE)
  AND Status = 'Aktywna';

3. Kalkulacja wieku należności (aging)

Przy windykacji i raportowaniu należności często liczy się przedziały 30‑, 60‑ i 90‑dniowe:

SELECT 
    NrFaktury,
    Kwota,
    CASE 
        WHEN DataWystawienia >= DATEADD(DAY, -30, GETDATE()) THEN '0-30 dni'
        WHEN DataWystawienia >= DATEADD(DAY, -60, GETDATE()) THEN '31-60 dni'
        WHEN DataWystawienia >= DATEADD(DAY, -90, GETDATE()) THEN '61-90 dni'
        ELSE '> 90 dni'
    END AS PrzedzialWindykacyjny
FROM Naleznosci;

4. Generowanie szeregów czasowych dla raportów

Przy braku tabeli kalendarza DATEADD pozwala dynamicznie wygenerować ciąg dat — przydatne w Power BI lub SSRS:

WITH SzeregDat AS (
    SELECT CAST('2026-01-01' AS DATE) AS Data
    UNION ALL
    SELECT DATEADD(DAY, 1, Data)
    FROM SzeregDat
    WHERE Data < '2026-12-31'
)
SELECT * FROM SzeregDat OPTION (MAXRECURSION 366);

5. Harmonogramowanie zadań i powiadomień

Aplikacje często potrzebują obliczyć „datę następnego wykonania” cyklicznego zadania. Dla przypomnienia co 90 dni:

UPDATE ZadaniaCykliczne
SET NastepneWykonanie = DATEADD(DAY, CoIleDni, ISNULL(OstatnieWykonanie, GETDATE()))
WHERE Aktywne = 1;

6. Obliczanie SLA i terminów dostaw

Dla zamówień z gwarantowanym czasem realizacji w dniach roboczych (z wyłączeniem weekendów) można napisać funkcję skalarną opartą o pętlę DATEADD(DAY, 1, ...) z kontrolą DATEPART(WEEKDAY, ...). Implementacja przekracza ramy tego artykułu, ale rdzeniem pozostaje DATEADD.

7. Przetwarzanie danych IoT i telemetrii

W hurtowniach danych przemysłowych często trzeba okienkować odczyty w interwałach 15‑sekundowych:

SELECT 
    DATEADD(SECOND, (DATEDIFF(SECOND, '2026-01-01', CzasPomiaru) / 15) * 15, '2026-01-01') AS Okno15s,
    AVG(Wartosc) AS Srednia
FROM OdczytyIoT
GROUP BY DATEADD(SECOND, (DATEDIFF(SECOND, '2026-01-01', CzasPomiaru) / 15) * 15, '2026-01-01');

Wydajność DATEADD w zapytaniach — indeksy, SARGability i pułapki

DATEADD użyty w klauzuli WHERE lub JOIN po lewej stronie kolumny czyni zapytanie non‑SARGable — optymalizator nie może wykorzystać indeksu przeszukującego (seek), co skutkuje scanem i drastycznym spadkiem wydajności przy dużych tabelach.

Źle (non‑SARGable):

SELECT * FROM Zamowienia
WHERE DATEADD(DAY, 30, DataZamowienia) > GETDATE();

Dobrze (SARGable):

SELECT * FROM Zamowienia
WHERE DataZamowienia > DATEADD(DAY, -30, GETDATE());

W pierwszym zapytaniu funkcja obudowuje kolumnę DataZamowienia — SQL Server nie potrafi „odwrócić” działania funkcji. W drugim funkcja działa na stałej GETDATE(), a porównanie odbywa się bezpośrednio na kolumnie — indeks może być użyty.

Koszty w liczbach (dane z SQL Server 2022, tabela 50 mln wierszy, indeks klastrowany na dacie):

WariantLogical readsCPU time (ms)
DATEADD na kolumnie~420 000~3 200
DATEADD na stałej~4~15

Różnica pięciorzędowa w odczytach logicznych to norma, nie wyjątek. W Azure SQL Database Hyperscale dodatkowo płaci się za jednostki DTU/vCore — nieoptymalne zapytania generują realne koszty finansowe.

DATEADD w chmurze — Azure SQL, Managed Instance, Microsoft Fabric

Rok 2026 przynosi coraz głębszą integrację silnika SQL Server z ekosystemem Microsoft Fabric. DATEADD działa w Fabric Data Warehouse i Fabric SQL Endpoint dokładnie tak samo, jak w pudełkowym SQL Server 2022 — co ułatwia migrację istniejącego kodu T‑SQL.

Różnice, które warto znać:

  • Azure SQL Database — pełna zgodność składniowa. Zwróć uwagę na limit 100 ns dla NANOSECOND (opisany wyżej).
  • Azure SQL Managed Instance — identyczna semantyka co SQL Server on‑premises, włącznie z agentem SQL i @@DATEFIRST.
  • Microsoft Fabric SQL EndpointDATEADD działa wyłącznie w trybie odczytu. Modyfikujące zapytania muszą być realizowane przez Data Pipeline lub Spark.
  • Azure Synapse Analytics (dedykowana pula SQL) — brak wsparcia dla rekurencyjnych CTE, ale DATEADD w zapytaniach analitycznych działa bez zmian.

DATEADD a strefy czasowe — datetimeoffset i AT TIME ZONE

W systemach globalnych sama funkcja DATEADD nie rozwiązuje problemu stref czasowych. Dodanie 8 godzin do wartości datetimeoffset nie uwzględnia zmian czasu letniego/zimowego. Prawidłowe podejście łączy DATEADD z AT TIME ZONE:

DECLARE @CzasUTC datetimeoffset = '2026-06-08 12:00:00 +00:00';

-- Konwersja na czas polski (CEST, UTC+2 latem)
SELECT @CzasUTC AT TIME ZONE 'Central European Standard Time' AS CzasPolska;

-- Dodanie 30 dni w strefie docelowej
SELECT DATEADD(DAY, 30, 
    CAST(@CzasUTC AT TIME ZONE 'Central European Standard Time' AS datetimeoffset)
) AS ZaMiesiacCzasPolska;

W 2026 roku Microsoft udostępnił zaktualizowaną bazę stref czasowych dla wszystkich wersji SQL Server w ramach aktualizacji zbiorczej CU15+ dla SQL Server 2022 — upewnij się, że Twój serwer ma wgraną najnowszą poprawkę, aby operacje na strefach czasowych były zgodne z faktycznymi zmianami regulacyjnymi w Twoim kraju.

Najczęstsze błędy i jak ich unikać

Błąd 1: niejawne konwersje typów

-- Błąd: datepart 'month' a liczba zmiennoprzecinkowa
SELECT DATEADD(MONTH, 1.5, '2026-06-08'); 
-- SQL Server zaokrągla 1.5 do 2 — niespodziewane przesunięcie o 2 miesiące

Rozwiązanie: zawsze przekazuj liczbę całkowitą lub jawnie rzutuj CAST(1.5 AS int).

Błąd 2: przepełnienie przy małych typach

-- smalldatetime ma zakres do 2079-06-06
SELECT DATEADD(YEAR, 100, CAST('2026-06-08' AS smalldatetime));
-- Błąd: przekroczenie zakresu

Rozwiązanie: używaj datetime2 jako domyślnego typu daty w nowych projektach.

Błąd 3: ignorowanie wpływu @@DATEFIRST przy WEEKDAY

DATEADD(WEEKDAY, ...) zachowuje się różnie w zależności od ustawienia @@DATEFIRST. Jeśli serwer ma @@DATEFIRST = 7 (niedziela jako pierwszy dzień tygodnia — ustawienie amerykańskie), a Ty oczekujesz poniedziałku, otrzymasz niespójne wyniki.

Częste pytania

Czy DATEADD działa z wartościami NULL?

Tak. Jeśli którykolwiek z trzech argumentów jest NULL, funkcja zwraca NULL. Nie generuje błędu.

Jaka jest różnica między DATEADD(DAY, 1, data) a DATEADD(DAYOFYEAR, 1, data)?

Z praktycznego punktu widzenia żadna — obie dodają jeden dzień. DAYOFYEAR jest rzadziej używany i może być mniej czytelny dla innych programistów.

Czy mogę używać zmiennych i podzapytań jako argumentu number?

Tak. number akceptuje dowolne wyrażenie zwracające int (lub bigint dla nanosekund), w tym kolumny, zmienne i wyniki podzapytań skalarnych.

Czy DATEADD uwzględnia lata przestępne?

Tak. DATEADD(DAY, 1, '2028-02-28') poprawnie zwróci 2028-02-29. Podobnie DATEADD(YEAR, 1, '2028-02-29') zwróci 2029-02-28, ponieważ rok 2029 nie jest przestępny.

Czy istnieje limit wartości argumentu number?

Dla datepart = SECOND maksymalna wartość to 68 lat w sekundach (ok. 2,14 mld) przy użyciu int. Przy NANOSECOND z bigint zakres jest istotnie większy. Próba przekroczenia zakresu daty docelowej spowoduje błąd „adding a value to a 'date' column caused an overflow”.

Czy DATEADD jest szybszy od ręcznego dodawania dni w kodzie aplikacji?

Zdecydowanie tak. DATEADD jest implementacją niskopoziomową w silniku SQL Server, napisaną w C++, i działa setki razy szybciej niż przesyłanie danych do aplikacji i manipulacja datą po stronie klienta. Wszelkie operacje na datach powinny być wykonywane jak najbliżej danych.

Czy SQL Server 2025/2026 planuje zmiany w DATEADD?

Zgodnie z roadmapą Microsoft opublikowaną na Microsoft Build 2025, DATEADD nie otrzyma żadnych zmian łamiących kompatybilność. Rozważane jest dodanie datepart = ISO_WEEK dla bezpośredniej pracy z numeracją tygodni ISO, ale nie znalazło się to jeszcze w oficjalnym backlogu wersji 2025.

Jak DATEADD zachowuje się przy zmianie czasu letniego na datetimeoffset?

DATEADD dodaje interwał czysto arytmetycznie — nie uwzględnia zmian czasu. Jeśli przechowujesz dane w datetimeoffset, łączenie z AT TIME ZONE jest niezbędne dla poprawnego uwzględnienia czasu letniego/zimowego.

Czy warto migrować stare wywołania DATEADD do DATETRUNC?

Nie. DATEADD i DATETRUNC to różne funkcje o różnym przeznaczeniu. Migruj wyłącznie te fragmenty kodu, które używają DATEADD/DATEDIFF do obcinania dat — tam DATETRUNC jest lepszym wyborem. Wszystkie pozostałe przypadki DATEADD (przesunięcia dat) nie mają alternatywy i powinny pozostać bez zmian.

Jak testować wydajność DATEADD w zapytaniach przed wdrożeniem na produkcję?

Użyj SET STATISTICS TIME, IO ON przed wykonaniem zapytania w środowisku testowym. Analizuj plany wykonania (Actual Execution Plan) pod kątem Index Scan vs. Index Seek. W Azure SQL Database skorzystaj z Query Performance Insights, aby obserwować wpływ zapytań na zużycie DTU.

Podsumowanie

Funkcja DATEADD to absolutny fundament pracy z datami w ekosystemie Microsoft SQL Server — od klasycznego on‑premises, przez Azure SQL Managed Instance, po środowiska Microsoft Fabric. Jej prostota składniowa bywa jednak zwodnicza: nieświadome owinięcie kolumny funkcją w WHERE potrafi zdławić wydajność wieloterabajtowej hurtowni danych, a nieuwzględnienie specyfiki @@DATEFIRST czy typów danych prowadzi do błędów trudnych do zdebugowania w testach.

Kluczowe zasady, które warto zapamiętać:

  • Funkcję stosuj zawsze po prawej stronie porównania — chroń indeksy.
  • W nowych projektach używaj datetime2 zamiast datetime lub smalldatetime.
  • Do obcinania dat (początek miesiąca, kwartału, roku) rozważ DATETRUNC.
  • Testuj zachowanie z NULL, wartościami ujemnymi i datami brzegowymi (przestępność, zmiana czasu).

Niezależnie od tego, czy budujesz system raportowy dla zarządu, czy pipeline ETL przetwarzający miliony zdarzeń IoT dziennie — solidna znajomość DATEADD to umiejętność, która zwraca się przy każdym przeglądzie planu wykonania.


Potrzebujesz legalnego oprogramowania Microsoft SQL Server, licencji CAL lub subskrypcji Azure do swojego środowiska? W KluczeSoft.pl znajdziesz sprawdzone rozwiązania w konkurencyjnych cenach — od SQL Server Standard po pakiety Microsoft 365 z pełnym dostępem do narzędzi analitycznych.

Sprawdź też

Potrzebujesz licencji? Microsoft SQL Server — sprawdź ofertę KluczeSoft.pl — legalne klucze, faktura VAT, dostawa e-mail.

<!-- INLINE-LINKS-V1 -->

Najczęściej zadawane pytania

Tak. Jeśli którykolwiek z trzech argumentów jest `NULL`, funkcja zwraca `NULL`. Nie generuje błędu.
Z praktycznego punktu widzenia żadna — obie dodają jeden dzień. `DAYOFYEAR` jest rzadziej używany i może być mniej czytelny dla innych programistów.
Tak. `number` akceptuje dowolne wyrażenie zwracające `int` (lub `bigint` dla nanosekund), w tym kolumny, zmienne i wyniki podzapytań skalarnych.
Tak. `DATEADD(DAY, 1, '2028-02-28')` poprawnie zwróci `2028-02-29`. Podobnie `DATEADD(YEAR, 1, '2028-02-29')` zwróci `2029-02-28`, ponieważ rok 2029 nie jest przestępny.
Dla `datepart = SECOND` maksymalna wartość to 68 lat w sekundach (ok. 2,14 mld) przy użyciu `int`. Przy `NANOSECOND` z `bigint` zakres jest istotnie większy. Próba przekroczenia zakresu daty docelowej spowoduje błąd „adding a value to a 'date' column caused an overflow”.
Zdecydowanie tak. `DATEADD` jest implementacją niskopoziomową w silniku SQL Server, napisaną w C++, i działa setki razy szybciej niż przesyłanie danych do aplikacji i manipulacja datą po stronie klienta. Wszelkie operacje na datach powinny być wykonywane jak najbliżej danych.
Zgodnie z roadmapą Microsoft opublikowaną na Microsoft Build 2025, `DATEADD` nie otrzyma żadnych zmian łamiących kompatybilność. Rozważane jest dodanie `datepart = ISO_WEEK` dla bezpośredniej pracy z numeracją tygodni ISO, ale nie znalazło się to jeszcze w oficjalnym backlogu wersji 2025.
`DATEADD` dodaje interwał czysto arytmetycznie — nie uwzględnia zmian czasu. Jeśli przechowujesz dane w `datetimeoffset`, łączenie z `AT TIME ZONE` jest niezbędne dla poprawnego uwzględnienia czasu letniego/zimowego.
Nie. `DATEADD` i `DATETRUNC` to różne funkcje o różnym przeznaczeniu. Migruj wyłącznie te fragmenty kodu, które używają `DATEADD`/`DATEDIFF` do obcinania dat — tam `DATETRUNC` jest lepszym wyborem. Wszystkie pozostałe przypadki `DATEADD` (przesunięcia dat) nie mają alternatywy i powinny pozostać bez zmian.
Użyj `SET STATISTICS TIME, IO ON` przed wykonaniem zapytania w środowisku testowym. Analizuj plany wykonania (Actual Execution Plan) pod kątem Index Scan vs. Index Seek. W Azure SQL Database skorzystaj z Query Performance Insights, aby obserwować wpływ zapytań na zużycie DTU.

Czy ten artykuł był pomocny?