POWRÓT NA STRONĘ SZKOŁY

Łączenie tabel

Podczas poprzednich zajęć wyszukiwaliśmy dane w jednej tabeli. Najczęściej jednak, występują bardziej skomplikowane sytuacje. Jak wiemy, zastosowanie relacji skutkuje "rozrzuceniem informacji" po wielu tabelach. W naszej bazie ksiegarnia_internetowa, jeżeli chcemy się dowiedzieć, jacy klieci złożyli zamówienia w danym miesiącu, to musimy przejrzeć tabele klienci i zamowienia. Jeżeli dodatkowo chcielibyśmy wiedzieć jakie książki zostały wtedy zamówione, musielibyśmy dodatkowo przejrzeć ksiazki_zamowione.

Aby za pomocą języka SQL uzyskać informacje znajdujące się w kilku tabelach, należy wykonać operację nazywaną łączeniem - ang. join. Chociaż sama zasada nie jest trudna do zrozumienia, to jednak łączenie tabel należy do bardziej złożonych operacji SQL. Należy tutaj powiedzieć, że jest kilka typów łączenia, z których każdy służy do innych celów.

Łączenie dwóch tabel

Omówimy wykonując ćwiczenie

Ćwiczenie 4_2_2_1. Łączenie dwóch tabel

Zastosujmy następujące zapytanie SQL:

SELECT zamowienia.zamowienie_id, zamowienia.wartosc, zamowienia.data
FROM klienci, zamowienia
WHERE klienci.nazwisko='Józef Koń'
AND klienci.klient_id=zamowienia.klient_id;
Wyszukiwanie danych poprzez łączenie dwóch tabel
Rysunek 4_2_2_1. Wyszukiwanie danych poprzez łączenie dwóch tabel

Omówimy teraz elementy, które wystąpiły w tym ćwiczeniu. Najpierw przejrzyj się tabelom klienci oraz zamowienia i porównaj wyniki wyszukiwania z danymi znajdującymi się w tych tabelach. Dla Józef Koń, klient_id=5. W tabeli zamowienia, klient_id o wartości równej 5 występuje 2 razy i właśnie te rekordy zostały pokazane w wyniku wyszukiwania. Uwagi do tego wyszukiwania:

  • W pierwszym wierszu zapytania SELECT zamowienia.zamowienie_id, zamowienia.wartosc, zamowienia.data mamy polecenie pokazania kolumn zamowienie_id, wartosc oraz data z tabeli zamowienia. Zwróć uwagę na zastosowanie kropki, która:
    • Jest niezbędna dla określenia, z której tabeli pochodzi dana kolumna, mamy na przykład klienci.klient_id, ale mamy także zamówienia.klient_id.
    • Zwiększa czytelność polecenia, ponieważ widzimy (przed kropką) tabelę, do której dana kolumna należy. Co prawda można nazwę tabeli pominąć w sytuacji, kiedy nazwy kolumn są unikatowe, niemniej właśnie z powodu czytelności powinno się stosować zapis z kropką.
  • W drugim wierszu mamy FROM klienci, zamowienia, a więc wymienione nazwy dwóch tabel z których będą brane dane. Nastąpiło tutaj łączenie tabel, ponieważ zamiast przecinka, który zastosowaliśmy, mogliśmy użyć takich słów kluczowych jak:
    • INNER JOIN - łączenie tabel po wspólnych rekordach, wyszukiwane są po prostu wiersze które do siebie pasują, w naszym przykładzie mają jednakowe wartości pól klient_id. Jest to najbardziej popularna operacja używana w wyszukiwaniach, zastosowana również w naszym przykładzie.
    • CROSS JOIN - łączenie rekordów obu tabel na zasadzie "każdy z każdym". Taki typ połączenia tabel nosi nazwę full join albo iloczyn kartezjański. Łączy on każdy wiersz pierwszej tabeli z każdym wierszem tabeli drugiej. W naszym przykładzie w wyniku takiego łączenia otrzymalibyśmy jedną dużą tabelę, w której każdy wiersz tabeli klienci byłby połączony z każdym wierszem tabeli zamowienia, bez względu na to, czy dany klient złożył to zamówienie czy nie. Jest to mało wyrafinowana operacja, zajmująca dużo pamięci i w większości przypadków nic nam nie dająca. W naszym przykładzie rozpatrywane są rekordy z zamówieniami złożonymi przez wskazanego klienta w połączeniu z rekordem zawierającym jego dane.
    Pasujące do siebie rekordy są odnajdowane dzięki zastosowaniu warunku połączenia (join condition) w klauzuli WHERE. W naszym przykładzie, wyrażenie warunkowe klienci.klient_id=zamowienia.klient_id jednoznacznie wskazuje pola które ustanawiają zwiazek miedzy tabelami. Dzięki niemu MYSQL pokazał w tabeli wynikowej tylko te wiersze, w których wartość pola klient_id z tabeli klienci odpowiada wartości pola klient_id z tabeli zamowienia.
  • Dodanie do zapytania warunku połączenia, spowodowało zmianę tytu połączenia na typ określany jako equi-join.

Łączenie trzech lub więcej tabel

Zasadą jest zestawianie tabel parami łączonymi poprzez określony warunek łączenia. W przypadku trzech tabel, można powiedzieć, że należy zdefiniować związki między danymi w jednej tabeli z danymi w drugiej tabeli, które to dane należy powiązać z danymi tabeli trzeciej.

W naszej bazie danych ksiegarnia_internetowa, aby znaleźć klientów, którzy nabyli książki dotyczące języka programowania C++ należy wziąć pod uwagę 4 tabele: klienci, zamowienia, ksiazki oraz ksiazki_zamowione.

  1. Aby powiązać dane z tabeli klienci, z danymi z tabeli zamowienia, trzeba przeanalizować wartości pól klient_id, tak jak to robiliśmy w ostatnim ćwiczeniu.
  2. Tabela zamowienia jest powiązana z tabelą ksiazki_zamowione, za pomocą pola zamowienie_id, natomiast tabela ksiazki_zamowione powiązana jest z tabelą ksiazki za pomocą pola isbn.

Ćwiczenie 4_2_2_2. Łączenie kilku tabel

Aby wykonać zadanie opisane powyżej, zastosujmy następujące zapytanie SQL:

SELECT klienci.nazwisko
FROM klienci, zamowienia, ksiazki_zamowione, ksiazki
WHERE klienci.klient_id=zamowienia.klient_id
AND zamowienia.zamowienie_id=ksiazki_zamowione.zamowienie_id
AND ksiazki_zamowione.isbn=ksiazki.isbn
AND ksiazki.tytul LIKE '%C++%';
Wyszukiwanie danych poprzez łączenie kilku tabel
Rysunek 4_2_2_2. Wyszukiwanie danych poprzez łączenie kliku tabel

Jak więc widzimy, panowie Ferdynand Kiepski oraz Jan Powolny, są miłośnikami programowania w C++.

Powiązaliśmy dane z 4 tabel. Aby je powiązać za pomocą połączenia typu equi-join, należało zastosować 3 różne warunki połączenia. W przypadku łączenia tabel, prawidłowością jest, że na każdą ich parę przypada jeden warunek. W rezultacie, suma wszystkich nałożonych warunków połączenia, jest o jeden mniejsza, niż liczba łączonych tabel.