Złączenie wewnętrzne - inner join
Możemy zaprezentować instrukcję SELECT zawierającą złączenie wewnętrzne (ang. inner join):
SELECT *
FROM Klienci
INNER JOIN Zamówienia
ON Klienci.IDKlienta = Zamówienia.IDKlienta
Przeanalizujmy każdą linię powyższej instrukcji. Słowo kluczowe SELECT w pierwszej linii i występujący po nim symbol gwiazdki (*) wskazują jedynie, że chcemy wybrać wszystkie kolumny z obu tabel. Druga linia z klauzulą FROM sygnalizuje, że pierwszą tabelą, którą wymieniamy, jest tabela Klienci. W trzeciej linii występuje nowe słowo kluczowe, INNER JOIN, za pomocą którego określamy, jaką tabelę chcemy dołączyć do uprzednio wymienionej. W tym przypadku jest to tabela Zamówienia.
Na koniec, w czwartej linii, użyto słowa kluczowego ON, które występuje w połączeniu ze słowem INNER JOIN. Określa ono, które dwie tabele i w jaki sposób zostają ze sobą połączone. W tym przypadku łączymy kolumnę IDKlienta z tabeli Klienci (Klienci.
IDKlienta) z kolumną IDKlienta z tabeli Zamówienia (Zamówienia.IDKlienta). Ponieważ kolumna IDKlienta ma taką samą nazwę zarówno w tabeli Klienci, jak i w tabeli Zamówienia, musimy podać nazwę tabeli jako przedrostek do kolumny IDKlienta. Dzięki
zastosowaniu przedrostka możemy odróżnić, z której tabeli pochodzi ta kolumna.
Powyższa instrukcja SELECT zwraca następujący wynik:
ID Klienta | Imię | Nazwisko | IDZamówienia | ID Klienta |
DataZamówienia | KwotaZamówienia |
1 | Sylwia | Dudziak | 1 | 1 | 2016-09-01 | 10,00 |
2 | Ryszard | Wieczorek | 2 | 2 | 2016-09-02 | 12,50 |
2 | Ryszard | Wieczorek | 3 | 2 | 2016-09-03 | 18,00 |
3 | Paweł | Janas | 4 | 3 | 2016-09-15 | 20,00 |
Przeanalizujmy otrzymane wyniki. Zarówno tabela Klienci, jak i tabela Zamówienia zawierały cztery wiersze. Patrząc na kolumnę IDZamówienia, można wywnioskować, że powyższa tabela zawiera dane ze wszystkich czterech wierszy z tabeli Zamówienia. Jednakże koncentrując uwagę na kolumnie IDKlienta, można zauważyć, że wymienionych zostało tylko trzech klientów. Dlaczego tak się stało? Powodem jest to, że klient z IDKlienta = 4 nie istnieje w tabeli Zamówienia. Ponieważ łączymy dwie tabele według pola IDKlienta, w tabeli Zamówienia nie istnieją wiersze pasujące do IDKlienta = 4 z tabeli Klienci.
Powyższa analiza pozwala na wyciągnięcie następującego wniosku: w wyniku zastosowania klauzuli INNER JOIN zwracane są wyłącznie dane, które istnieją w obu złączonych ze sobą tabelach. W następnym rozdziale omówimy alternatywny sposób łączenia tabel, dzięki któremu informacja o kliencie, którego IDKlienta = 4, znajdzie się w wyniku zapytania, nawet jeśli nie będą istniały dla niego wiersze w tabeli Zamówienia.
Zauważ również, że dane klienta Ryszarda Wieczorka występują w powyższym wyniku dwukrotnie. W tabeli Klienci dla tego klienta występował tylko jeden wiersz, dlaczego zatem jego dane pojawiły się w wyniku dwukrotnie? Stało się tak dlatego, że w wynikach,
dzięki zastosowaniu klauzuli INNER JOIN, zwrócone zostały wszystkie możliwe sparowania wierszy z obu tabel. Ponieważ w przypadku Ryszarda w tabeli Zamówienia występują dwa wiersze, oba można powiązać z wierszem zawierającym informacje o tym kliencie w tabeli Klienci. Stąd też dane o Ryszardzie Wieczorku zwracane są w wyniku dwukrotnie.
Być może zastanawiasz się, dlaczego tego rodzaju złączenie nosi nazwę złączenia wewnętrznego. Jest tak dlatego, że istnieją dwa główne typy tego rodzaju złączeń, a mianowicie złączenia wewnętrzne oraz zewnętrzne.
Kolejność tabel w złączeniach wewnętrznych
Dzięki zastosowaniu złączenia wewnętrznego dane zwracane są w przypadku, gdy istnieją elementy wspólne dla obu określonych tabel. W poprzedniej instrukcji SELECT w klauzuli FROM wymieniliśmy tabelę Klienci, natomiast tabela Zamówienia znalazła się w klauzuli INNER JOIN. Przywodzi to na myśl pytanie, czy ma znaczenie, która tabela jest wymieniona jako pierwsza. Jak się okazuje, kolejność, w jakiej są one wymienione w przypadku zastosowania złączenia wewnętrznego, może zostać zmieniona bez wpływu na otrzymywane wyniki. Poniższe dwie instrukcje SELECT są identyczne w sensie logicznym i zwracają te same dane:
SELECT *
FROM Klienci
INNER JOIN Zamówienia
ON Klienci.IDKlienta = Zamówienia.IDKlienta
SELECT *
FROM Zamówienia
INNER JOIN Klienci
ON Zamówienia.IDKlienta = Klienci.IDKlienta
Jedyna różnica między powyższymi instrukcjami polega na tym, że pierwsze zapytanie wyświetliłoby najpierw kolumny z tabeli Klienci, a następnie z tabeli Zamówienia. W przypadku wyniku otrzymanego po wykonaniu drugiej instrukcji kolejność wyświetlania
kolumn byłaby odwrotna. Poza tym zwrócone dane niczym by się od siebie nie różniły. Pamiętaj, że SQL nie jest językiem proceduralnym. Nie precyzuje zatem dokładnej kolejności, w jakiej zadanie ma zostać wykonane. Określa jedynie, jaka jest pożądana logika, według której ma zostać zwrócony wynik, natomiast zadanie de facto wykonywane jest przy uwzględnieniu charakterystyk konkretnej bazy danych. SQL jako taki nie określa dokładnie, w jaki sposób baza danych fizycznie pobiera dane ani też która tabela powinna być wzięta pod uwagę jako pierwsza. To oprogramowanie bazy danych determinuje najbardziej
optymalny sposób wykonywania instrukcji SELECT.
Alternatywna składnia złączeń wewnętrznych
W poprzednich przykładach w celu zdefiniowana złączeń wewnętrznych użyliśmy słów kluczowych INNER JOIN oraz ON. Złączenie tego typu może być także określone za pomocą klauzuli FROM i WHERE. Poniższa instrukcja SELECT łącząca tabele Klienci i Zamówienia jest nam już znana:
SELECT *
FROM Klienci
INNER JOIN Zamówienia
ON Klienci.IDKlienta = Zamówienia.IDKlienta
Alternatywny sposób zdefiniowana złączenia wewnętrznego, bez użycia słów kluczowych
INNER JOIN i ON, jest następujący:
SELECT *
FROM Klienci, Zamówienia
WHERE Klienci.IDKlienta = Zamówienia.IDKlienta
W zaprezentowanym powyżej innym wariancie składni, zamiast użyć słowa kluczowego INNER JOIN, aby określić dodatkowe tabele, które mają zostać dołączone, wymieniamy jedynie wszystkie pożądane tabele w klauzuli FROM. Zamiast klauzuli ON, za pośrednictwem której określaliśmy, w jaki sposób tabele mają zostać powiązane, w tym przypadku użyliśmy klauzuli WHERE, aby określić związek między tabelami.
Mimo że zaprezentowany powyżej odmienny format działa doskonale i daje te same wyniki, nie polecamy go stosować. Zaletą słów kluczowych INNER JOIN i ON jest to, że wyraźnie precyzują logikę tworzenia złączeń. Taki jest ich jedyny cel. Chociaż możliwe jest określenie związku między tabelami w klauzuli WHERE, znaczenie instrukcji SQL nie jest w tym przypadku już tak oczywiste, gdy klauzula ta służy do sprecyzowania kryteriów selekcji, a jednocześnie do określenia związku między wieloma tabelami.
Język SQL. Przyjazny podręcznik. Wydanie II Autor: Larry Rockoff Wydawnictwo: Helion