Łączenie trzech i więcej tabel, zapis złączenia warunkami w klauzuli WHERE, aliasy tabel oraz samozłączenie tabeli z samą sobą.
INNER JOIN łączy dwie tabele. Realne pytania sięgają jednak często dalej: „który uczeń, z jakiej klasy, dostał jaką ocenę i od którego nauczyciela" wymaga zajrzenia do trzech albo czterech tabel naraz.
Dwa zapisy tego samego. Złączenie da się zapisać na dwa sposoby. Pierwszy to JOIN ... ON ... – nowszy i czytelniejszy, bo warunek złączenia stoi tuż przy łączonej tabeli. Drugi to wymienienie tabel po FROM po przecinku i przeniesienie warunków złączenia do WHERE. Ten drugi zapis jest starszy, ale bardzo często spotykany w materiałach do matury i w Accessie, więc trzeba umieć go czytać.
Oba dają ten sam wynik. Przy zapisie przecinkowym warunki złączenia łączy się operatorem AND, tak jak wszystkie pozostałe warunki.
Reguła: n tabel wymaga n−1 warunków złączenia. Trzy tabele to dwa warunki, cztery tabele to trzy warunki. To najprostszy sposób sprawdzenia, czy niczego nie pominąłeś – i najczęstsza przyczyna nieprawidłowych wyników, gdy warunku zabraknie.
Co się dzieje, gdy warunku zabraknie. Baza nie zgłasza błędu. Skleja wtedy każdy wiersz z każdym, więc przy 5 uczniach i 5 ocenach dostajesz 25 wierszy zamiast 5. Wynik wygląda poprawnie – ma właściwe kolumny i sensowne wartości – tylko jest bez sensu. Podejrzanie duża liczba wierszy to pierwszy sygnał, że brakuje warunku.
Aliasy tabel. Gdy tabel jest kilka, pełne nazwy w każdym odwołaniu robią się nieczytelne. Alias to krótka nazwa zastępcza nadawana tabeli po FROM. Nie jest tylko wygodą: gdy kolumna o tej samej nazwie występuje w dwóch tabelach, alias jest jedynym sposobem, żeby wskazać, o którą chodzi. Bez tego baza zgłosi, że nazwa jest niejednoznaczna.
Samozłączenie – ta sama tabela dwa razy. Niektóre pytania porównują wiersze wewnątrz jednej tabeli: „którzy uczniowie mają wyższą średnią od Kowalskiej", „które pary uczniów są z tej samej klasy". Rozwiązaniem jest wymienienie tej samej tabeli dwukrotnie, pod dwoma różnymi aliasami – baza traktuje je wtedy jak dwie niezależne tabele i można je ze sobą porównywać.
To jedyny przypadek, w którym alias jest bezwzględnie konieczny: bez dwóch różnych nazw nie da się zapisać warunku odnoszącego się do obu „kopii" tabeli naraz.
-- Zapis przecinkowy: tabele po FROM, warunki złączenia w WHERE SELECT u.nazwisko, u.klasa, o.przedmiot, o.ocena FROM uczniowie AS u, oceny AS o WHERE u.id = o.uczen_id
| nazwisko | klasa | przedmiot | ocena |
|---|---|---|---|
| Kowalska | 3A | informatyka | 5 |
| Kowalska | 3A | matematyka | 4 |
| Nowak | 3B | informatyka | 3 |
| Wiśniewski | 3A | informatyka | 6 |
| Wiśniewski | 3A | matematyka | 5 |
-- Ten sam wynik zapisany nowszą składnią JOIN ... ON SELECT u.nazwisko, u.klasa, o.przedmiot, o.ocena FROM uczniowie AS u INNER JOIN oceny AS o ON u.id = o.uczen_id
| nazwisko | klasa | przedmiot | ocena |
|---|---|---|---|
| Kowalska | 3A | informatyka | 5 |
| Kowalska | 3A | matematyka | 4 |
| Nowak | 3B | informatyka | 3 |
| Wiśniewski | 3A | informatyka | 6 |
| Wiśniewski | 3A | matematyka | 5 |
-- Samozłączenie: pary uczniów z tej samej klasy. -- Warunek u1.id < u2.id usuwa duplikaty i pary ucznia z samym sobą. SELECT u1.nazwisko AS pierwszy, u2.nazwisko AS drugi, u1.klasa FROM uczniowie AS u1, uczniowie AS u2 WHERE u1.klasa = u2.klasa AND u1.id < u2.id
| pierwszy | drugi | klasa |
|---|---|---|
| Kowalska | Wiśniewski | 3A |
| Nowak | Dąbrowski | 3B |
Policz tabele i warunki. Trzy tabele po FROM wymagają dwóch warunków złączenia. Jeśli masz trzy tabele i jeden warunek, wynik będzie zawyżony – i to jest błąd, którego baza nie wychwyci za Ciebie.
Poprzedzaj aliasem każdą kolumnę, która występuje w więcej niż jednej tabeli. Zwykle dotyczy to id, ale też nazwa czy data. Dopisanie aliasu tam, gdzie nie jest konieczny, nie jest błędem – warto to robić odruchowo przy każdym złączeniu.
Przy samozłączeniu uważaj na duplikaty. Warunek porównujący same wartości zwróci każdą parę dwukrotnie (raz w każdej kolejności) plus pary każdego wiersza z samym sobą. Dołożenie warunku na kluczach – „pierwszy mniejszy od drugiego" – rozwiązuje oba problemy naraz.
Sprawdź liczbę wierszy wyniku. Uczeń z trzema ocenami pojawi się w wyniku trzy razy. To normalne, ale jeśli zadanie pyta „ilu uczniów", trzeba policzyć unikalne wartości, a nie wiersze.
Do nauki i czytania – ten z JOIN ... ON, bo oddziela warunki złączenia od warunków filtrowania. Do matury – ten, którego wymaga zadanie albo narzędzie; oba są poprawne. Warto umieć czytać oba, bo materiały bywają pisane w starszej konwencji.
W Accessie tak. W wielu innych bazach AS przy nazwie tabeli jest opcjonalne i wystarczy napisać nazwę zastępczą po spacji. Dla czytelności lepiej pisać AS zawsze.
Tak – wystarczy tyle różnych aliasów, ile kopii potrzebujesz. W praktyce powyżej dwóch robi się to bardzo trudne do prześledzenia i zwykle znak, że problem da się rozwiązać podzapytaniem.
Zagadnienia z tego samego obszaru matury – warto je powtórzyć razem: