BLOK 20 · 2 godz. SQL Podzapytania Daty

SQL: podzapytania i operacje na datach

Informatyka Rozszerzona · Klasa 4 · Semestr II · Blok 20/30

1. Czym jest podzapytanie?

Podzapytanie (ang. subquery) to zapytanie SQL umieszczone wewnątrz innego zapytania. Wykonuje się jako pierwsze, a jego wynik jest wykorzystywany przez zapytanie zewnętrzne. Podzapytania pozwalają rozwiązywać problemy, których nie da się wyrazić prostym JOIN-em.

2. Podzapytanie w klauzuli WHERE

-- znajdź uczniów, których średnia jest wyższa niż średnia całej szkoły SELECT imie, nazwisko FROM Uczniowie WHERE srednia > (SELECT AVG(srednia) FROM Uczniowie);

Podzapytanie (SELECT AVG(srednia) FROM Uczniowie) wykonuje się jako pierwsze i zwraca pojedynczą liczbę, którą zapytanie zewnętrzne wykorzystuje w porównaniu.

3. Operator IN z podzapytaniem

Gdy podzapytanie zwraca wiele wartości (nie jedną), używamy operatora IN zamiast znaku porównania.

-- znajdź imiona uczniów, którzy mają jakąkolwiek ocenę niedostateczną SELECT imie, nazwisko FROM Uczniowie WHERE id_ucznia IN ( SELECT id_ucznia FROM Oceny WHERE ocena = 1 );

4. Podzapytanie skorelowane

Podzapytanie skorelowane odwołuje się do kolumny z zapytania zewnętrznego — jest wykonywane osobno dla każdego wiersza zapytania głównego (wolniejsze, ale czasem konieczne).

-- znajdź uczniów z najwyższą oceną W SWOJEJ klasie SELECT u.imie, o.ocena FROM Uczniowie u JOIN Oceny o ON u.id_ucznia = o.id_ucznia WHERE o.ocena = ( SELECT MAX(o2.ocena) FROM Oceny o2 WHERE o2.id_klasy = u.id_klasy -- odwołanie do tabeli zewnętrznej! );

5. Operacje na datach

Typowe zadania maturalne wymagają obliczeń na datach: wieku, liczby dni między zdarzeniami, filtrowania po roku/miesiącu. Składnia różni się nieco między silnikami SQL — poniżej przykłady dla SQLite (używanego m.in. w arkuszach egzaminacyjnych CKE).

-- wiek ucznia na podstawie daty urodzenia SELECT imie, (strftime('%Y', 'now') - strftime('%Y', data_urodzenia)) AS wiek FROM Uczniowie; -- uczniowie urodzeni w konkretnym roku SELECT imie FROM Uczniowie WHERE strftime('%Y', data_urodzenia) = '2007'; -- liczba dni między dwiema datami SELECT julianday('2026-06-20') - julianday(data_zapisu) AS dni_w_szkole FROM Uczniowie;

Uwaga na formaty dat

SQL oczekuje dat w formacie RRRR-MM-DD (ISO 8601). Data zapisana jako tekst w innym formacie (np. 20.06.2026) nie będzie poprawnie porównywana ani sortowana!

6. Ćwiczenia praktyczne

Ćwiczenie 1 — uczniowie powyżej średniej klasy

Napisz zapytanie z podzapytaniem skorelowanym, które znajdzie wszystkich uczniów, których indywidualna ocena jest wyższa niż średnia ocen w ich własnej klasie.

Ćwiczenie 2 — najstarsi absolwenci

Mając tabelę Uczniowie z kolumną data_urodzenia, napisz zapytanie wypisujące imię i wiek trzech najstarszych uczniów, posortowanych malejąco według wieku (użyj ORDER BY i LIMIT).

SELECT imie, (strftime('%Y','now') - strftime('%Y', data_urodzenia)) AS wiek FROM Uczniowie ORDER BY data_urodzenia ASC LIMIT 3;

Sprawdź wiedzę

1. Kiedy w podzapytaniu należy użyć operatora IN zamiast znaku =?

2. Czym charakteryzuje się podzapytanie skorelowane?

3. W jakim formacie SQL (ISO 8601) należy zapisywać daty, aby poprawnie je porównywać i sortować?

Podsumowanie bloku