Daty i czas to nie tylko abstrakcyjne liczby, ale klucz do bezcennej części informacji w danych. W prawdziwym życiu często spotykasz się z datami: na przykład analiza sprzedaży według miesięcy, filtrowanie po dacie urodzenia pracowników albo porównywanie przedziałów czasowych. Wiedza, jak operować datami, pozwala budować bardziej elastyczne zapytania i robić zaawansowane analizy.
Przykłady, gdzie praca z datami jest mega ważna:
- Analiza sprzedaży za konkretny miesiąc.
- Zliczanie liczby użytkowników, którzy zarejestrowali się w ostatnim roku.
- Tworzenie raportów według przedziałów czasowych (np. miesięczne przychody).
W PostgreSQL jest masa funkcji do pracy z datami, a teraz ogarniemy tylko te najbardziej przydatne.
Podstawowe funkcje do pracy z datami i czasem
Funkcja NOW() zwraca aktualną datę i godzinę serwera bazy danych. Używasz jej, gdy chcesz znać dokładny aktualny czas. Przykład: chcesz zapisać czas utworzenia nowego rekordu.
SELECT NOW();
Przykładowy wynik:
2023-11-05 15:23:45.123456+00
Przykład użycia: Chcesz dodać zamówienie z aktualną datą i godziną:
INSERT INTO orders (order_id, order_date, total_amount)
VALUES (1, NOW(), 150.00);
Komentarz: tutaj
NOW() automatycznie wrzuci aktualną datę i godzinę do kolumny
order_date.
Jak dokładnie działa operator INSERT dowiesz się w kolejnych wykładach :P
Funkcja CURRENT_DATE
Jeśli potrzebujesz tylko aktualnej daty bez godziny, użyj CURRENT_DATE. Ona zwraca tylko rok, miesiąc i dzień.
Składnia:
SELECT CURRENT_DATE;
Przykładowy wynik:
2023-11-05
Przykład użycia: Załóżmy, że chcesz pobrać rekordy z dzisiaj:
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
Komentarz: tutaj porównujemy datę z kolumny
order_date z dzisiejszą datą.
Trochę humoru. NOW() to jak twoja kawa w pracy: gotowa tu i teraz. A CURRENT_DATE to jak kalendarz na ścianie: tylko data, bez szczegółów.
Wyciąganie części daty za pomocą DATE_PART()
Funkcja DATE_PART() pozwala nam wyciągnąć konkretną część daty, np. rok, miesiąc, dzień, godzinę albo minutę. To wygodne, np. żeby policzyć liczbę zamówień w danym roku albo sprawdzić dzień tygodnia.
Składnia:
DATE_PART('część', data)
Przykład:
SELECT DATE_PART('year', NOW()) AS current_year;
Przykładowy wynik:
| current_year |
|---|
| 2025 |
Części daty, które możesz wyciągnąć:
year: rok.month: miesiąc.day: dzień.hour: godzina.minute: minuta.second: sekunda.dow: dzień tygodnia (0 = niedziela).
Przykład 2: Wyciągamy miesiąc z aktualnej daty.
SELECT DATE_PART('month', CURRENT_DATE) AS current_month;
Wynik:
| current_month |
|---|
| 6 |
Możesz użyć DATE_PART() do bardziej zaawansowanych obliczeń. Na przykład:
Chcesz wybrać tylko tych użytkowników, którzy urodzili się w tym roku:
SELECT *
FROM students
WHERE DATE_PART('year', birth_date) = DATE_PART('year', CURRENT_DATE);
Przykładowy wynik:
| id | first_name | last_name | birth_date | grade |
|---|---|---|---|---|
| 1 | Otto | Art | 2025-03-12 | 9 |
| 2 | Anna | Pal | 2025-07-08 | 8 |
| 3 | Piu | Wolf | 2025-01-22 | 10 |
| 4 | Eva | Go | 2025-09-30 | 7 |
| 5 | Dan | Sok | 2025-06-14 | 9 |
Praktyczne przykłady
W niektórych przykładach pojawią się operatory, których jeszcze nie znasz. Spoko, niedługo będziesz je ogarniać z zamkniętymi oczami. Po prostu chcę ci pokazać więcej realnych przykładów z życia. No i trochę cię zaintrygować :)
Przykład 1: Wyznaczanie wieku użytkownika
Załóżmy, że mamy tabelę users z datą urodzenia każdego użytkownika. Chcemy policzyć ich wiek.
Zapytanie:
SELECT user_id, first_name, last_name,
DATE_PART('year', CURRENT_DATE) - DATE_PART('year', birth_date) AS age
FROM users;
Po prostu odejmujemy lata z aktualnej daty i daty urodzenia. To szybki, ale nieprecyzyjny sposób na wiek.
Przykładowy wynik:
| user_id | first_name | last_name | age |
|---|---|---|---|
| 101 | Alex | Lin | 25 |
| 102 | Maria | Chi | 30 |
| 103 | Tor | Coz | 22 |
| 104 | Nat | Ive | 27 |
| 105 | Don | Sok | 35 |
Przykład 2: Filtrowanie po czasie
Jeśli chcesz wybrać wszystkie zamówienia z ostatniej godziny:
SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '1 hour';
Zwróć uwagę, jak wygodne jest użycie INTERVAL (oznaczenie przedziału czasu).
Przykład 3: Grupowanie po miesiącach
Chcesz policzyć liczbę zamówień w każdym miesiącu bieżącego roku:
SELECT DATE_PART('month', order_date) AS order_month, COUNT(*) AS order_count
FROM orders
WHERE DATE_PART('year', order_date) = DATE_PART('year', CURRENT_DATE)
GROUP BY DATE_PART('month', order_date)
ORDER BY order_month;
Grupowanie jest po numerze miesiąca, a wynik sortowany według niego.
Przykładowy wynik:
| order_month | order_count |
|---|---|
| 1 | 120 |
| 2 | 95 |
| 3 | 134 |
| 4 | 110 |
| 5 | 42 |
Przykład 4: Wyciąganie dnia tygodnia
Chcesz sprawdzić, w który dzień tygodnia jest najwięcej zamówień:
SELECT DATE_PART('dow', order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DATE_PART('dow', order_date)
ORDER BY order_count DESC;
Komenda DATE_PART('dow') zwróci dzień tygodnia dla każdego zamówienia jako liczbę, gdzie 0 — niedziela, 1 — poniedziałek itd. DOW to skrót od DayOfWeek — dzień tygodnia.
Przykładowy wynik:
| day_of_week | order_count |
|---|---|
| 5 | 210 |
| 4 | 190 |
| 3 | 175 |
| 2 | 160 |
| 1 | 140 |
| 6 | 120 |
| 0 | 95 |
Zwróć uwagę na typowe błędy
Praca z datami często powoduje ból głowy przez błędy. Oto kilka typowych problemów, na które możesz się natknąć:
Format czasu i daty: kiedy używasz NOW() albo innej funkcji zwracającej datę z godziną, zawsze sprawdzaj jej format. Na przykład, jeśli porównujesz order_date z CURRENT_DATE, upewnij się, że godzina jest ignorowana albo jawnie ustawiona.
Data jako tekst: często w bazach daty są przechowywane jako tekst (np. string). Jeśli spróbujesz użyć funkcji do pracy z datami (np. DATE_PART()), dostaniesz błąd. Upewnij się, że dane mają typ DATE albo TIMESTAMP.
Różne strefy czasowe: jeśli twój serwer działa w jednej strefie czasowej, a dane zbierasz z innej, może być zamieszanie. Rozważ użycie strefy czasowej TIMESTAMPTZ.
GO TO FULL VERSION