Złączenia lewostronne - LEFT JOIN
Mamy trzy tabele. W tabeli Klienci znajdują się następujące dane:
IDKlienta | ImięKlienta | NazwiskoKlienta |
1 | Sylwia | Dudziak |
2 | Ryszard | Wieczorek |
3 | Paweł | Janas |
4 | Szymon | Majkowski |
Tabela Zamówienia ma następującą zawartość:
IDZamówienia | IDKlienta | DataZamówienia | KwotaZamówienia |
1 | 1 | 2016-09-01 | 10,00 |
2 | 2 | 2016-09-02 | 12,50 |
3 | 2 | 2016-10-03 | 18,00 |
4 | 3 | 2016-09-15 | 20,00 |
Tabela Zwroty ma natomiast postać:
IDZwrotu | IDZamówienia | DataZwrotu | KwotaZwrotu |
---|---|---|---|
1 | 1 | 2016-09-02 | 5,00 |
2 | 3 | 2016-09-18 | 18,00 |
Zbudujmy teraz instrukcję SELECT, w której za pomocą klauzuli LEFT JOIN dokonamy złączenia trzech powyższych tabel:
SELECT
Klienci.ImięKlienta AS 'Imię klienta',
Klienci.NazwiskoKlienta AS 'Nazwisko klienta',
Zamówienia.DataZamówienia AS 'Data zamówienia',
Zamówienia.KwotaZamówienia AS 'Kwota zamówienia',
Zwroty.DataZwrotu AS 'Data zwrotu',
Zwroty.KwotaZwrotu AS 'Kwota zwrotu'
FROM Klienci
LEFT JOIN Zamówienia
ON Klienci.IDKlienta = Zamówienia.IDKlienta
LEFT JOIN Zwroty
ON Zamówienia.IDZamówienia = Zwroty.IDZamówienia
ORDER BY Klienci.NazwiskoKlienta, Klienci.ImięKlienta, Zamówienia.DataZamówienia
Jej wynik jest następujący:
Imię klienta |
Nazwisko klienta |
Data zamówienia |
Kwota zamówienia |
Data zwrotu | Kwota zwrotu |
Sylwia | Dudziak | 2016-09-01 | 10,00 | 2016-09-02 | 5,00 |
Paweł | Janas | 2016-09-15 | 20,00 | NULL | NULL |
Szymon | Majkowski | NULL | NULL | NULL | NULL |
Ryszard | Wieczorek | 2016-09-02 | 12,50 | NULL | NULL |
Ryszard | Wieczorek | 2016-09-03 | 18,00 | 2016-09-18 | 18,00 |
RÓŻNICE W RAMACH INNYCH BAZ DANYCH: Oracle
W przeciwieństwie do SQL Server i MySQL, Oracle zazwyczaj wyświetla daty w formacie DD-MMM-YY. Na przykład data z powyższej tabeli, 2016-09-02, zostałaby wyświetlona w Oracle jako 02-SEP-16. Jednak bez względu na to, której bazy danych używasz, format wyświetlania dat będzie się różnić, w zależności od ustawień bazy danych.
Zanim przeanalizujemy powyższą instrukcję SELECT, zwróćmy uwagę na dwa interesujące aspekty widoczne w zwróconych przez nią danych. Po pierwsze, w przypadku Szymona Majkowskiego w wyniku pojawiło się tylko jego imię i nazwisko, a w pozostałych kolumnach jest wartość NULL. Powodem tego jest brak danych dla tego klienta w tabeli Zamówienia. Dzięki zastosowaniu złączenia zewnętrznego, choć klient ten nie złożył żadnego zamówienia, możemy zobaczyć jego podstawowe dane. Gdybyśmy zastosowali klauzulę INNER JOIN zamiast LEFT JOIN, nie zobaczylibyśmy w wyniku żadnych wierszy zawierających dane Szymona Majkowskiego.
Podobnie w wynikach nie ma danych o zwrotach dotyczących zamówienia z dnia 2016-09-02 złożonego przez Ryszarda Wieczorka, a także zamówienia Pawła Janasa — z tego względu, że w tabeli Zwroty nie istnieją wiersze odnoszące się do tych zamówień. Gdybyśmy do złączenia wykorzystali klauzulę INNER JOIN zamiast klauzuli LEFT JOIN, w wyniku nie pojawiłyby się wiersze z danymi dla tych właśnie zamówień.
Spójrzmy teraz na samą instrukcję SELECT. W pierwszych kilku liniach wymieniane są kolumny, co nie jest dla Ciebie żadnym zaskoczeniem. Zauważ, że zamiast wykorzystywać aliasy tabel, wymieniamy w tym przypadku wszystkie kolumny, stosując ich pełne nazwy oraz nazwę tabeli jako przedrostek.
Pierwsza wymieniona jest tabela Klienci. Została ona wyszczególniona zaraz po słowie kluczowym FROM. Druga jest tabela Zamówienia, która jest wymieniana po pierwszym słowie kluczowym LEFT JOIN. Następująca po niej klauzula ON wskazuje, w jaki sposób tabela Zamówienia jest powiązana z tabelą Klienci. Trzecia wymieniona została tabela Zwroty, która znajduje się po drugim słowie kluczowym LEFT JOIN. Występująca po nim klauzula ON określa, w jaki sposób tabela Zwroty jest złączoną z tabelą Zamówienia.
Niezwykle istotne jest zwrócenie uwagi na fakt, że kolejność, w jakiej wymieniane są tabele w odniesieniu do słowa kluczowego LEFT JOIN, ma znaczenie. Gdy chcemy z niego skorzystać, tabela wymieniana po jego lewej stronie jest zawsze tabelą nadrzędną. Tabela po prawej stronie słowa kluczowego LEFT JOIN to tabela podrzędna. Poprzez złączenie tabeli
podrzędnej z tabelą nadrzędną otrzymujemy wszystkie wiersze z tabeli nadrzędnej, nawet wówczas, gdy dla niektórych wierszy z tej tabeli nie istnieją do dołączenia wiersze w tabeli podrzędnej.
W pierwszej klauzuli LEFT JOIN tabela Klienci znajduje się po jej lewej stronie, natomiast tabela Zamówienia po prawej stronie tej klauzuli. Oznacza to, że tabela Klienci jest tabelą nadrzędną, a tabela Zamówienia podrzędną. Innymi słowy, chcemy zobaczyć wszystkie wybrane dane z tabeli Klienci, nawet jeśli w tabeli podrzędnej nie istnieją dane, które można do nich dołączyć.
Podobnie w drugiej klauzuli LEFT JOIN, tabela Zamówienia znajduje się po jej lewej stronie, natomiast tabela Zwroty po prawej. To oznacza, że tabela Zamówienia jest tabelą nadrzędną, zaś tabela Zwroty podrzędną. Chcemy tym samym wyświetlić wszystkie zamówienia, nawet jeśli w przypadku którychkolwiek z nich nie wystąpiły żadne zwroty. Jak ma to miejsce w przypadku złączeń wewnętrznych, w wyniku mogą znaleźć się wiersze zawierające powtórzone dane z jednej tabeli. Zdarza się to wówczas, gdy w dołączanej tabeli klucz wskazuje na więcej niż dwa rekordy. W naszym przykładzie taka sytuacja zaistniała w przypadku Ryszarda Wieczorka. Jako że złożył on dwa zamówienia, jego dane osobowe pojawiły się w dwóch oddzielnych wierszach.
Na końcu instrukcji znajduje się klauzula ORDER BY. Dzięki niej dane zostały po prostu wyświetlone w pożądanej kolejności.
Weryfikacja występowania wartości NULL
W wyniku powyższej instrukcji SELECT znajdował się jeden klient, który nie złożył zamówienia, a także dwa zamówienia, które nie podlegały zwrotowi. W przeciwieństwie do klauzuli INNER JOIN, dzięki wykorzystaniu klauzuli LEFT JOIN wiersze z brakującymi
wartościami zostały uwzględnione w wyniku.
Aby zweryfikować zdobytą przez nas wiedzę o klauzuli LEFT JOIN, spróbujmy teraz zbudować instrukcję SELECT, za pomocą której wyszczególnimy tylko te zamówienia, dla których nie miał miejsca zwrot kosztów. Rozwiązaniem jest dodanie do instrukcji klauzuli WHERE, za pomocą której będziemy mogli zweryfikować istnienie bądź brak wartości NULL:
SELECT
Klienci.ImięKlienta AS 'Imię klienta',
Klienci.NazwiskoKlienta AS 'Nazwisko klienta',
Zamówienia.DataZamówienia AS 'Data zamówienia',
Zamówienia.KwotaZamówienia AS 'Kwota zamówienia'
FROM Klienci
LEFT JOIN Zamówienia
ON Klienci.IDKlienta = Zamówienia.IDKlienta
LEFT JOIN Zwroty
ON Zamówienia.IDZamówienia = Zwroty.IDZamówienia
WHERE Zamówienia.IDZamówienia IS NOT NULL
AND Zwroty.IDZwrotu IS NULL
ORDER BY Klienci.NazwiskoKlienta, Klienci.ImięKlienta, Zamówienia.DataZamówienia
Wynik tej instrukcji jest następujący:
Imię klienta |
Nazwisko klienta |
Data zamówienia | Kwota zamówienia |
Paweł | Janas | 2016-09-15 | 20,00 |
Ryszard | Wieczorek | 2016-09-02 | 12,50 |
Klauzula WHERE weryfikuje najpierw, która kolumna Zamówienia.IDZamówienia nie zawiera wartości NULL. Dzięki temu możemy być pewni, że w wyniku nie znajdą się klienci, którzy nigdy nie złożyli zamówienia. Za pomocą drugiej część klauzuli WHERE wybierane są tylko te wiersze, dla których kolumna Zwroty.IDZwrotu zawiera wartości NULL. Gwarantuje to, że zwrócone zostaną tylko te zamówienia, dla których nie było zwrotu.
Zauważ, że tym razem zrezygnowaliśmy z wyświetlenia informacji o dacie zwrotu oraz jego kwocie. Stało się tak, ponieważ wiedzieliśmy, że w kolumnach zawierających te informacje przy uwzględnieniu kryteriów wyboru zdefiniowanych w naszym zapytaniu otrzymalibyśmy w wyniku wartości NULL.
Język SQL. Przyjazny podręcznik. Wydanie II Autor: Larry Rockoff Wydawnictwo: Helion