Podstawy SQL, takie jak wyciąganie danych (SELECT) i proste łączenie dwóch tabel, to świetny początek. Egzaminatorzy CKE uwielbiają jednak sprawdzać, czy potrafisz pójść o krok dalej. Zadania maturalne z baz danych niemal zawsze wymagają uporządkowania wyników (np. sortowanie alfabetyczne SQL), odfiltrowania pogrupowanych już danych (tu do gry wchodzi HAVING) oraz połączenia trzech lub więcej tabel naraz. Co więcej, w polskich szkołach króluje Microsoft Access, który ma swoją własną, dość specyficzną i rygorystyczną składnię.
W tym poradniku rozbijemy te zaawansowane koncepcje na proste, życiowe przykłady. Opanujesz zapytania zagnieżdżone, zrozumiesz, dlaczego Access krzyczy na Ciebie o nawiasy w JOIN-ach, i nauczysz się pisać kwerendy, które bezbłędnie celują w klucz odpowiedzi.
Nasza Baza Szkoleniowa: Zawody Sportowe
Aby nasze SQL JOIN przykłady miały sens, oprzemy się na typowym schemacie maturalnym. Wyobraź sobie bazę danych obsługującą międzyszkolne zawody sportowe. Mamy trzy tabele:
- Uczniowie:
ID_Ucznia(Klucz podstawowy),Imie,Nazwisko,Szkola - Zawody:
ID_Zawodow(Klucz podstawowy),NazwaDyscypliny,DataZawodow - Wyniki:
ID_Wyniku(Klucz podstawowy),ID_Ucznia(Klucz obcy),ID_Zawodow(Klucz obcy),UzyskanePunkty
Zwróć uwagę na tabelę łączącą!
Tabela Wyniki to klasyczna tabela asocjacyjna (łącząca). Rozwiązuje ona relację 'wiele do wielu' (jeden uczeń może startować w wielu zawodach, a w jednych zawodach startuje wielu uczniów). To standardowy trik na maturze.
Porządek musi być: Sortowanie (ORDER BY)
CKE rzadko prosi po prostu o 'wypisanie danych'. Niemal zawsze pojawia się klauzula: 'wyniki posortuj alfabetycznie po nazwisku, a następnie po imieniu' lub 'od największej liczby punktów'. Do tego służy klauzula ORDER BY.
SQL ORDER BY ASC DESC – jak to działa?
Klauzula ORDER BY musi znajdować się na samym końcu zapytania (po WHERE, po GROUP BY i po HAVING). Przyjmuje dwa modyfikatory kierunku:
ASC(Ascending) – sortowanie rosnące (od A do Z, od 0 do 9). Jest to wartość domyślna, więc jeśli jej nie wpiszesz, SQL i tak użyje ASC.DESC(Descending) – sortowanie malejące (od Z do A, od 9 do 0).
Sortowanie alfabetyczne SQL (po wielu kolumnach)
Zadanie: „Wypisz imiona i nazwiska wszystkich uczniów. Wyniki posortuj alfabetycznie po nazwisku. Jeśli uczniowie mają to samo nazwisko (np. Jan Kowalski i Anna Kowalska), posortuj ich dodatkowo alfabetycznie po imieniu.”
SELECT Imie, Nazwisko
FROM Uczniowie
ORDER BY Nazwisko ASC, Imie ASC;Zauważ, że wymieniamy kolumny po przecinku. SQL najpierw grupuje i sortuje według Nazwisko, a dopiero w obrębie identycznych nazwisk odpala sortowanie po Imie. Zapis ASC dodaliśmy dla przejrzystości, ale zapytanie zadziała tak samo bez niego.
Sortowanie mieszane
Zadanie: „Wypisz identyfikatory uczniów i ich punkty. Wyniki posortuj od najwyższej liczby punktów (malejąco), ale przy równej liczbie punktów posortuj po ID ucznia rosnąco.”
SELECT ID_Ucznia, UzyskanePunkty
FROM Wyniki
ORDER BY UzyskanePunkty DESC, ID_Ucznia ASC;Odwieczny dylemat: WHERE czy HAVING?
To jedno z najważniejszych zagadnień, na którym uczniowie tracą punkty. Obie klauzule służą do filtrowania wyników (odrzucania niechcianych wierszy), ale robią to na zupełnie innych etapach działania zapytania.
| Cechy | WHERE | HAVING |
|---|---|---|
| Kiedy działa? | PRZED grupowaniem (GROUP BY) | PO grupowaniu (GROUP BY) |
| Co filtruje? | Pojedyncze wiersze (rekordy z tabeli) | Całe grupy rekordów (worki z danymi) |
| Funkcje agregujące (COUNT, SUM)? | ZABRONIONE. Nie możesz napisać WHERE SUM(x) > 10 | DOZWOLONE, a wręcz do tego HAVING zostało stworzone |
Przykład: Odróżnienie w praktyce
Zadanie: „Podaj ID uczniów, którzy wystartowali w WIĘCEJ NIŻ 2 zawodach.”
Analiza: Aby dowiedzieć się, ile razy wystartował uczeń, musimy zliczyć jego rekordy w tabeli Wyniki. Słowo 'zliczyć' oznacza COUNT(). Skoro używamy COUNT(), musimy zgrupować dane (GROUP BY), a skoro filtrujemy po wyniku funkcji zliczającej, musimy użyć HAVING.
SELECT ID_Ucznia, COUNT(ID_Zawodow) AS LiczbaStartow
FROM Wyniki
GROUP BY ID_Ucznia
HAVING COUNT(ID_Zawodow) > 2;Błąd, którego musisz unikać!
Napisanie WHERE COUNT(ID_Zawodow) > 2 spowoduje błąd składni w MS Access (i każdym innym silniku bazy). Baza powie Ci: 'Nie mogę zliczać przed zgrupowaniem, więc nie każ mi filtrować po czymś, czego jeszcze nie policzyłam!'.
Łączenie WHERE i HAVING w jednym zapytaniu
Zadanie: „Tylko dla uczniów ze szkoły 'LO Batory', policz łączną sumę ich punktów. Wyświetl tylko tych z Batorego, których suma punktów przekroczyła 100.”
SELECT Uczniowie.Imie, Uczniowie.Nazwisko, SUM(Wyniki.UzyskanePunkty) AS SumaPunktow
FROM Uczniowie
INNER JOIN Wyniki ON Uczniowie.ID_Ucznia = Wyniki.ID_Ucznia
WHERE Uczniowie.Szkola = 'LO Batory' -- 1. Odrzucamy innych uczniów przed grupowaniem
GROUP BY Uczniowie.Imie, Uczniowie.Nazwisko -- 2. Grupujemy Batorego w worki
HAVING SUM(Wyniki.UzyskanePunkty) > 100; -- 3. Odrzucamy worki, gdzie suma <= 100Złożone SQL JOIN przykłady: Koszmar nawiasów w MS Access
Połączenie dwóch tabel to pikuś. Zapisujesz FROM Tabela A INNER JOIN Tabela B ON A.id = B.id. Co jednak, gdy zadanie wymaga wyciągnięcia imienia ucznia, nazwy dyscypliny i liczby punktów? Musimy połączyć TRZY tabele: Uczniowie, Wyniki i Zawody.
W standardowym SQL (np. MySQL, PostgreSQL) po prostu dopisujesz kolejne JOIN-y jeden pod drugim. Ale Microsoft Access (którego używasz na maturze) jest w tej kwestii bardzo kapryśny – wymaga użycia nawiasów dla każdego kolejnego łączenia.
Schemat łączenia 3 tabel w MS Access
SELECT ...
FROM
(Tabela1 INNER JOIN Tabela2 ON Tabela1.Klucz = Tabela2.KluczObcy)
INNER JOIN Tabela3 ON Tabela2.InnyKlucz = Tabela3.Klucz;Wyobraź to sobie tak: MS Access potrafi łączyć tabele tylko w parach. Najpierw łączy Tabelę 1 i 2 (zamykamy to w nawias), tworząc z nich jedną, dużą 'wirtualną' tabelę. Następnie do tej nowej bryły dokleja Tabelę 3.
Pełne zapytanie z 3 tabelami (Przykład)
Zadanie: „Wypisz imię i nazwisko ucznia, nazwę dyscypliny, w której brał udział, oraz liczbę punktów, którą zdobył.”
SELECT Uczniowie.Imie, Uczniowie.Nazwisko, Zawody.NazwaDyscypliny, Wyniki.UzyskanePunkty
FROM
(Uczniowie
INNER JOIN Wyniki ON Uczniowie.ID_Ucznia = Wyniki.ID_Ucznia)
INNER JOIN Zawody ON Wyniki.ID_Zawodow = Zawody.ID_Zawodow;A jeśli musisz połączyć 4 tabele?
Dodajesz kolejny nawias z przodu!
FROM ((T1 INNER JOIN T2 ON ...) INNER JOIN T3 ON ...) INNER JOIN T4 ON ...
Kreator kwerend w Accessie tworzy te nawiasy automatycznie, ale jeśli piszesz kod ręcznie w widoku SQL, zapomnienie o nich to najczęstszy powód błędu 'Błąd składniowy w operacji JOIN'.
Wyższy poziom abstrakcji: Zapytania zagnieżdżone (Podzapytania)
Czasem zadanie jest tak sformułowane, że nie da się go rozwiązać jednym przebiegiem. Wtedy z pomocą przychodzą zapytania zagnieżdżone – czyli kwerenda umieszczona wewnątrz innej kwerendy (najczęściej w klauzuli WHERE).
Kiedy używać podzapytań?
Klasycznym wyzwalaczem podzapytania na maturze jest sformułowanie: 'Znajdź tych, którzy zdobyli więcej niż średnia' albo 'Wypisz uczniów, którzy nie brali udziału w zawodach'.
Przykład 1: Porównanie do wartości wyliczonej dynamicznie
Zadanie: „Wypisz imiona i nazwiska uczniów, którzy zdobyli w pojedynczym starcie wynik wyższy niż średnia wszystkich wyników ze wszystkich zawodów.”
Nie możemy napisać WHERE UzyskanePunkty > AVG(UzyskanePunkty), bo funkcja agregująca zepsuje zapytanie. Musimy najpierw obliczyć średnią osobnym zapytaniem i podłożyć jej wynik.
SELECT Uczniowie.Imie, Uczniowie.Nazwisko, Wyniki.UzyskanePunkty
FROM Uczniowie
INNER JOIN Wyniki ON Uczniowie.ID_Ucznia = Wyniki.ID_Ucznia
WHERE Wyniki.UzyskanePunkty > (
SELECT AVG(UzyskanePunkty)
FROM Wyniki
);Silnik bazy najpierw wykona to, co jest w nawiasie (np. wyjdzie mu średnia 45). Następnie podmieni całe podzapytanie na tę liczbę i przefiltruje główną tabelę: WHERE UzyskanePunkty > 45.
Przykład 2: Użycie operatora IN
Jeśli Twoje podzapytanie zwraca więcej niż jedną wartość (całą kolumnę), nie możesz użyć znaku =. Musisz użyć operatora IN.
Zadanie: „Wypisz dane uczniów, którzy startowali w jakichkolwiek zawodach w roku 2024.”
SELECT Imie, Nazwisko
FROM Uczniowie
WHERE ID_Ucznia IN (
SELECT ID_Ucznia
FROM Wyniki
INNER JOIN Zawody ON Wyniki.ID_Zawodow = Zawody.ID_Zawodow
WHERE YEAR(Zawody.DataZawodow) = 2024
);Dlaczego Access lubi podzapytania?
Choć powyższe zadanie można by zrealizować po prostu potrójnym JOIN-em z klauzulą DISTINCT, to podejście z podzapytaniem jest często logiczniejsze dla ludzkiego mózgu podczas presji egzaminacyjnej. Oddzielasz warunek wyszukiwania (wnętrze kwerendy) od tego, co chcesz ostatecznie wyświetlić (zewnętrzna kwerenda).
Wielki finał: Pełne zadanie maturalne krok po kroku
Teraz połączymy wszystko: złożonego JOINa, filtrowanie przed zgrupowaniem, grupowanie, odrzucanie grup i sortowanie. Jeśli zrozumiesz to zapytanie, żadne zadanie z SQL nie sprawi Ci kłopotu.
Zadanie: Aktywni pływacy
Dla każdej szkoły podaj jej nazwę oraz łączną sumę punktów zdobytych przez jej uczniów, ale tylko w dyscyplinie 'Plywanie'. Uwzględnij w zestawieniu wyłącznie te szkoły, w których suma punktów z pływania przekroczyła 200. Wyniki posortuj malejąco według zdobytych punktów, a w przypadku remisów, alfabetycznie po nazwie szkoły.
- Tabele: Musimy połączyć
Uczniowie(skąd weźmiemy szkołę),Wyniki(skąd weźmiemy punkty) iZawody(skąd weźmiemy dyscyplinę). Access wymaga nawiasów! - WHERE: Filtrujemy rekordy PRZED podsumowaniem – interesuje nas tylko 'Plywanie'.
- GROUP BY: Chcemy sumę dla każdej szkoły, więc grupujemy po
Szkola. - HAVING: Odrzucamy słabe szkoły po zgrupowaniu: SUM(UzyskanePunkty) > 200.
- ORDER BY: Sortujemy podwójnie: najpierw suma punktów DESC, potem nazwa szkoły ASC.
SELECT Uczniowie.Szkola, SUM(Wyniki.UzyskanePunkty) AS SumaPunktowPlywania
FROM
(Uczniowie
INNER JOIN Wyniki ON Uczniowie.ID_Ucznia = Wyniki.ID_Ucznia)
INNER JOIN Zawody ON Wyniki.ID_Zawodow = Zawody.ID_Zawodow
WHERE Zawody.NazwaDyscypliny = 'Plywanie'
GROUP BY Uczniowie.Szkola
HAVING SUM(Wyniki.UzyskanePunkty) > 200
ORDER BY SUM(Wyniki.UzyskanePunkty) DESC, Uczniowie.Szkola ASC;Zatrzymaj się na chwilę i przeanalizuj ten kod. Jeśli widzisz tu logiczną opowieść: 'Z tych połączonych tabel weź tylko pływanie, zbierz to do worków z napisem nazwy szkoły, wywal z tych worków te lżejsze niż 200 punktów, i na koniec ustaw od najcięższego do najlżejszego' – to znaczy, że właśnie wygrałeś z SQL.
Najczęściej zadawane pytania (FAQ)
❓ Najczęściej zadawane pytania (FAQ)
Czy muszę pisać słówka takie jak INNER JOIN wielkimi literami?
Nie, SQL nie rozróżnia wielkości liter w przypadku komend (jest case-insensitive). Oznacza to, że 'select' zadziała tak samo jak 'SELECT'. Przyjmuje się jednak standard używania wielkich liter dla komend, aby oddzielić je wizualnie od nazw tabel i kolumn, co drastycznie zwiększa czytelność, zwłaszcza na papierze!
Czy mogę sortować po aliasie kolumny (np. AS SumaPunktow) w ORDER BY?
W MS Access zazwyczaj TAK. Możesz napisać 'ORDER BY SumaPunktow DESC'. Warto jednak wyrobić sobie nawyk kopiowania całej funkcji (np. 'ORDER BY SUM(UzyskanePunkty) DESC'), ponieważ niektóre inne silniki SQL (i wybrane starsze wersje Accessa przy specyficznych kwerendach) mogą zgłosić błąd nierozpoznania aliasu na etapie sortowania.
Dlaczego przy złożonych JOIN-ach wyskakuje mi 'Niezgodność typów w wyrażeniu kryterium'?
Prawdopodobnie próbujesz połączyć kolumny o różnych formatach danych. Pamiętaj, aby zawsze łączyć Klucz Podstawowy (zwykle typ AutoNumerowanie/Liczbowy) z odpowiednim Kluczem Obcym (Typ Liczbowy). Jeśli spróbujesz połączyć kolumnę tekstową z liczbową, Access wyrzuci ten właśnie błąd.
Czym się różni LEFT JOIN od INNER JOIN na maturze?
INNER JOIN zwraca TYLKO rekordy, które mają dopasowanie w obu tabelach (np. tylko uczniów, którzy wystartowali). LEFT JOIN zwraca WSZYSTKIE rekordy z lewej tabeli i dopasowuje do nich prawą. Jeśli uczeń nie wystartował, i tak się wyświetli, ale na miejscu wyników pojawi się puste pole (NULL). Takie zapytania pojawiają się najczęściej przy poleceniach w stylu: 'Wypisz uczniów, którzy NIE wystartowali w żadnych zawodach'.
Pamiętaj, by przed napisaniem skomplikowanego SQL na maturze najpierw rozrysować sobie logikę zapytania w brudnopisie. Krok po kroku łącz tabele, filtruj, grupuj i sortuj. Poćwicz te zaawansowane kwerendy na arkuszach z lat poprzednich, a na egzaminie MS Access nie będzie miał przed Tobą żadnych tajemnic!
Bazy Danych i Arkusze Kalkulacyjne
MS Access, SQL i zaawansowany Excel na maturę
jednorazowo
Szukasz więcej praktyki? Sprawdź pełny kurs do matury z informatyki.