0Pricing
Coding Interview Prep · Lekcja

Działania na datach i interwały

Dodawanie i odejmowanie okresów oraz obliczanie różnic między datami.

Działania na datach i interwały to bezpłatna lekcja Coding Interview Prep na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Coding Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Dlaczego arytmetyka dat pojawia się na rozmowach kwalifikacyjnych

Arytmetyka dat jest jedną z najbardziej praktycznych umiejętności w SQL, dlatego osoby prowadzące rozmowy kwalifikacyjne często wykorzystują ją w przypadku stanowisk analitycznych i backendowych. Niemal każde pytanie biznesowe ma komponent czasowy: ostatnie 30 dni, zamówienia na tydzień, liczba dni od rejestracji.

Trudność polega na tym, że funkcje dat są najmniej ustandaryzowaną częścią SQL. Ta sama operacja ma inną składnię w PostgreSQL, MySQL i SQL Server. Dobry kandydat najpierw jasno przedstawia ideę, a następnie dostosowuje składnię do danego dialektu.

  • Dodawanie lub odejmowanie okresu
  • Obliczanie różnicy między dwiema datami
  • Praca z wartościami typu INTERVAL

Typ INTERVAL

W PostgreSQL i w standardzie SQL okres czasu jest pełnoprawną wartością zwaną interwałem. Dodaje się go do daty lub znacznika czasu za pomocą zwykłych operatorów + i -.

To najczytelniejszy sposób wyrażenia „30 dni temu” lub „za 3 miesiące”, a osoby prowadzące rozmowy kwalifikacyjne cenią go, ponieważ zapis przypomina język naturalny.

SELECT
  CURRENT_DATE,
  CURRENT_DATE + INTERVAL '7 days'   AS next_week,
  CURRENT_DATE - INTERVAL '1 month'  AS last_month,
  NOW() + INTERVAL '90 minutes'      AS soon;

Dodawanie okresów w różnych dialektach

Podczas rozmowy kwalifikacyjnej często pada pytanie: „jak dodać 7 dni w MySQL, a jak w SQL Server?”. Znajomość trzech najważniejszych dialektów świadczy o praktycznym doświadczeniu.

  • PostgreSQL: d + INTERVAL '7 days'
  • MySQL: DATE_ADD(d, INTERVAL 7 DAY)
  • SQL Server: DATEADD(day, 7, d)

Koncepcja jest identyczna; zmienia się tylko zapis. Zawsze należy określić, dla którego dialektu pisane jest zapytanie.

-- MySQL
SELECT DATE_ADD(order_date, INTERVAL 7 DAY) AS due_date FROM orders;

-- SQL Server
SELECT DATEADD(day, 7, order_date) AS due_date FROM orders;

Różnica między dwiema datami

Drugą częścią arytmetyki dat jest obliczanie odstępu między dwiema datami. Wynik zależy od jednostki i dialektu.

W PostgreSQL odejmowanie od siebie dwóch wartości typu date bezpośrednio daje całkowitą liczbę dni. Odejmowanie dwóch wartości typu timestamp daje natomiast interwał.

-- Postgres: date - date returns an integer (days)
SELECT shipped_date - order_date AS days_to_ship
FROM orders;

DATEDIFF i jego pułapki

Funkcja DATEDIFF istnieje w MySQL i SQL Server, ale działa w nich inaczej — to częsta pułapka na rozmowach kwalifikacyjnych.

  • MySQL: DATEDIFF(end, start) zwraca wyłącznie całkowitą liczbę dni.
  • SQL Server: DATEDIFF(unit, start, end) przyjmuje jednostkę i zlicza przekroczenia granic, a nie pełne jednostki.

To zachowanie na granicach ma znaczenie: DATEDIFF(year, '2023-12-31', '2024-01-01') w SQL Server zwraca 1, mimo że upłynął tylko jeden dzień.

-- SQL Server: counts boundaries, not elapsed time
SELECT DATEDIFF(year, '2023-12-31', '2024-01-01'); -- 1
SELECT DATEDIFF(day,  '2023-12-31', '2024-01-01'); -- 1

Poprawne obliczanie wieku w latach

„Oblicz wiek klienta w latach” to klasyczne zadanie. Proste podzielenie różnicy dni przez 365 daje niedokładne wyniki z powodu lat przestępnych. PostgreSQL udostępnia funkcję AGE(), która zwraca rzeczywisty interwał kalendarzowy.

Aby uzyskać poprawną całkowitą liczbę lat, należy wyodrębnić część wieku oznaczającą lata.

-- Postgres
SELECT
  birth_date,
  AGE(CURRENT_DATE, birth_date)               AS exact_age,
  EXTRACT(YEAR FROM AGE(CURRENT_DATE, birth_date)) AS age_years
FROM customers;

Przykład: zamówienia z ostatnich 30 dni

To niemal uniwersalny filtr na rozmowach kwalifikacyjnych. Właściwe podejście polega na porównaniu kolumny z datą obliczonego punktu odcięcia, a nie na opakowaniu kolumny funkcją.

Porównanie order_date ze stałym punktem odcięcia pozwala użyć indeksu utworzonego dla order_date. Do kwestii indeksu wrócimy później.

SELECT COUNT(*) AS recent_orders
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days';

Przedziały półotwarte dla miesiąca kalendarzowego

Gdy pytanie dotyczy „wszystkich zamówień z marca 2024”, należy unikać używania BETWEEN '2024-03-01' AND '2024-03-31' dla kolumny ze znacznikiem czasu. Takie podejście pomija wiersze z godziny 23:00 w dniu 31 marca i jest podatne na błędy graniczne.

Poprawny wzorzec to przedział półotwarty: >= początek i < początek następnego miesiąca. Działa on niezależnie od precyzji kolumny.

SELECT *
FROM orders
WHERE order_ts >= DATE '2024-03-01'
  AND order_ts <  DATE '2024-04-01';

EXTRACT i części daty

Wydobywanie pojedynczego składnika z daty jest codzienną czynnością w pracy z raportami. Standardową funkcją jest EXTRACT(part FROM d), obsługiwana przez PostgreSQL i MySQL.

  • EXTRACT(YEAR FROM d), MONTH, DAY
  • EXTRACT(DOW FROM d) — dzień tygodnia
  • SQL Server używa zamiast tego DATEPART(weekday, d)

Uwaga: wyodrębnienie samego MONTH łączy marce z różnych lat w jedną grupę, co rzadko jest oczekiwanym rezultatem.

SELECT
  EXTRACT(YEAR  FROM order_ts) AS yr,
  EXTRACT(MONTH FROM order_ts) AS mo,
  COUNT(*) AS n
FROM orders
GROUP BY 1, 2
ORDER BY 1, 2;

Trudniejszy przykład: dni do następnych urodzin

To trudniejsze zadanie arytmetyczne, które łączy wyodrębnianie i dodawanie. Należy zbudować datę tegorocznych urodzin na podstawie miesiąca i dnia urodzenia, a jeśli urodziny już minęły, przesunąć ją na następny rok.

Omówienie tego zadania na głos pokazuje osobie prowadzącej rozmowę, że potrafi Pan/Pani rozumować o przypadkach brzegowych, takich jak urodziny, które już odbyły się w bieżącym roku.

-- Postgres
SELECT
  name,
  CASE
    WHEN MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) >= CURRENT_DATE
    THEN MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) - CURRENT_DATE
    ELSE MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int + 1,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) - CURRENT_DATE
  END AS days_until
FROM customers;

Pierwszy i ostatni dzień miesiąca

„Podaj ostatni dzień miesiąca każdego zamówienia” sprawdza, czy sięga się po funkcję wbudowaną, czy próbuje odtworzyć jej działanie. PostgreSQL łączy DATE_TRUNC z arytmetyką interwałów, natomiast MySQL udostępnia bezpośrednio funkcję LAST_DAY().

Sposób na uzyskanie ostatniego dnia miesiąca w Postgresie jest następujący: obciąć datę do początku miesiąca, dodać miesiąc i odjąć jeden dzień.

-- Postgres
SELECT
  DATE_TRUNC('month', order_ts)                              AS month_start,
  DATE_TRUNC('month', order_ts) + INTERVAL '1 month - 1 day' AS month_end
FROM orders;

-- MySQL: LAST_DAY(order_ts)

Szybkie sprawdzenie

Sprawdź, czy rozumiesz różnice między dialektami w obliczaniu różnicy dat.

Podsumowanie: arytmetyka dat i interwały

Najważniejsze wnioski przed rozmową kwalifikacyjną:

  • Należy używać wartości INTERVAL z operatorami +/- w Postgresie, DATE_ADD/DATEDIFF w MySQL oraz DATEADD/DATEDIFF w SQL Server.
  • DATEDIFF w SQL Server zlicza przekroczenia granic, a nie upływ pełnych jednostek — to najważniejsza pułapka.
  • Aby obliczyć wiek w latach, należy wyodrębnić wartość z AGE(), zamiast dzielić liczbę dni przez 365.
  • Najnowsze wiersze należy filtrować, porównując kolumnę z obliczonym punktem odcięcia, a dla zakresów miesięcznych używać przedziałów półotwartych (>= start AND < next).

Najpierw należy przedstawić koncepcję, a następnie dostosować ją do dialektu.

Często zadawane pytania

Czy lekcja „Działania na datach i interwały” jest bezpłatna?

Tak — pełny tekst „Działania na datach i interwały” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Coding Interview Prep, przejdź na CoddyKit PRO. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „Działania na datach i interwały”?

Dodawanie i odejmowanie okresów oraz obliczanie różnic między datami. Ćwiczysz Coding Interview Prep z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Coding Interview Prep?

Nie wymagamy żadnego doświadczenia. Coding Interview Prep w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Działania na datach i interwały”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Coding Interview Prep?

Tak. Każda lekcja Coding Interview Prep zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Działania na datach i interwały
  2. Obcinanie i grupowanie dat
  3. Analizowanie i formatowanie ciągów znaków
  4. Strefy czasowe i znaczniki czasu
← Powrót do Coding Interview Prep