Przedstawiłem już ogólną koncepcje tworzenia łączeń w języku SQL. Wykonaliśmy też proste złączenia dwóch tabel. Tym razem Darmowy Kurs SQL zostaje rozszerzony o metody na pobieranie przy pomocy instrukcji SELECT danych z wielu tabel na raz.
Zaczynasz Darmowym Kurs SQL? Pierwsza część dostępna tutaj: Kurs SQL #01: Wprowadzenie i środowisko
Instrukcja SELECT i wiele tabel
W większości przypadków kiedy korzystamy z bazy danych pobieramy dane z wielu tabel. Dzisiejszy złożony świat przekłada się na rozbudowane relacje w bazach. Stosunkowo rzadko jest potrzeba pobrania informacji z pojedynczej tabeli. Wynika to choćby z wspomnianego już wcześniej w Darmowym Kursie SQL dążenia do ograniczenia duplikacji danych w bazie.
Nie istnieje żadne ograniczenie co do ilości tabel mogących brać udział w złączeniach. Zawsze liczba złączeń w zapytaniu będzie o jeden mniejsza od ilości tabel w nim biorących.
Typy złączeń
Złączenia wewnętrzne – INNER JOIN
Ten typ złączenia wykorzystywaliśmy już w naszych zapytaniach. Rzuć zatem okiem jak wygląda takie złączenie w nieco bardziej rozbudowanym zapytaniu. W przykładach nie stosuje aliasów, dla łatwiejszego zrozumienia zapytań 😉
select
oe.customers.cust_first_name,
oe.customers.cust_last_name,
oe.orders.order_mode,
oe.order_items.quantity,
oe.product_information.list_price
from oe.customers, oe.orders, oe.order_items, oe.product_information
where customers.customer_id = orders.customer_id
and oe.orders.order_id = oe.order_items.order_id
and oe.order_items.product_id= oe.product_information.product_id;
CUST_FIRST_NAME | CUST_LAST_NAME | ORDER_MODE | QUANTITY | LIST_PRICE |
---|---|---|---|---|
Harrison | Sutherland | direct | 53 | 16 |
Harrison | Sutherland | direct | 47 | 81 |
Harrison | Sutherland | direct | 47 | 46 |
Harrison | Sutherland | direct | 48 | 21 |
Powyższy przykład wykorzystuje cztery tabele: CUSTOMERS, ORDERS, ORDER_ITEMS i PRODUCT_INFORMATION. Jak się pewnie domyślasz mamy w nich informacje o klientach, zamówieniach, produktach które w tych zamówieniach są i o samych produktach dostępnych w sklepie.
Równozłączenia wykonane w zapytaniu:
- CLIENTS i ORDERS po kluczach CUSTOMER_ID
- ORDERS i ORDER_ITEMS po kluczach ORDER_ID
- ORDER_ITEMS I PRODUCT_INFORMATION po kluczach PRODUCT_ID
Jak widzisz mamy cztery tabele biorące udział w zapytaniu, co przekłada się na trzy złączenia. Wyświetlane są tylko te wiersze, które mają dopasowanie po drugiej stronie danego złączenia. W wynikach nie zobaczysz produktów które nigdy nie była zamawiane, czy użytkowników sklepu którzy nigdy nic nie zamówili.
Jeżeli preferujesz naukę prze oglądanie materiałów video zachęcam Cię do sprawdzenia mojego Kursu online SQL w Praktyce!
Kurs dostępny pod linkiem: Kurs SQL
Złączenia zewnętrzne – OUTER JOIN
Złączenie tego typu wyświetla dany wiersz nawet, jeżeli nie ma dla niego dopasowania po drugiej stronie złączenia. Baza danych Oracle jako operator tego typu złączeń wykorzystuje znak plus w nawiasach (+).
select
oe.order_items.order_id,
oe.product_information.product_name
from oe.order_items, oe.product_information
where oe.order_items.product_id (+) = oe.product_information.product_id
order by 1 desc;
ORDER_ID | PRODUCT_NAME |
---|---|
– | HD 6GB /I |
– | Chemicals – RCP |
– | SPNIX3.3 C/DU |
– | C for SPNIX3.3 – Seat/U |
Nieco uprościłem nasze zapytanie. Skupmy się na części gdzie tabela z spisem zamówień łączy się z tabelą informacji o produktach. Czy każde zamówienie musi mieć odwołanie do jakiegoś produktu? Zdecydowanie tak 😉 Czy każdy produkt w sklepie musi mieć odwołanie do jakiegoś zamówienia? Oczywiście nie! Przecież w sklepie mogą być produkty, których nikt nigdy nie kupił.
Gdy nie użyjemy operatora (+) baza danych zwróci listę zamówień z przyporządkowanymi do nich produktami. Produkty nigdy nie zamawiane nie pojawią się w wyniku zapytania. Poprzez zastosowanie operatora (+) poinstruowaliśmy bazę danych o chęci wyświetlenia kompletu produktów, nawet jeśli nie ma dla nich przyporządkowanego zamówienia.
Klauzule ORDER BY dodałem tylko po to, aby wyświetlić nasze NULL’e na górze wyników zapytania. Warto zapamiętać, że w bazie danych Oracle NULL traktowany jest jako wartość większa od jakiejkolwiek wartości znanej. Dlatego też wykonałem sortowanie malejące 😉 Miej na uwadze, że traktowanie NULL jako wartość największa lub najmniejsza jest zależne od silnika bazy danych.
✅Operator (+) stawiasz zawsze po przeciwnej stronie niż tabela z której chcesz pozyskać komplet wierszy 😉
Złączenie własne
Kolejny typ złączeń to złączenia wewnętrze. Tutaj z kolei robimy coś nietypowego na pierwszy rzut oka. Łączymy tabele z nią samą 😉 Zastanawiasz się zapewne w jakim celu mamy robić coś takiego. Najlepszy do zobrazowania zagadnienia będzie koronny i stary jak świat przykład spisu pracowników.
SELECT w.first_name
|| ' '
|| w.last_name
|| ' jest podwładnym '
|| m.first_name
|| ' ' ||
m.last_name
FROM hr.employees w, hr.employees m
WHERE w.manager_id = m.employee_id
ORDER BY w.first_name;
W.FIRST_NAME||”||W.LAST_NAME||’JESTPODWŁADNYM’||M.FIRST_NAME||”||M.LAST_NAME |
---|
Adam Fripp jest podwładnym Steven King |
Alana Walsh jest podwładnym Kevin Mourgos |
Alberto Errazuriz jest podwładnym Steven King |
Alexander Khoo jest podwładnym Den Raphaely |
Jak widzisz skorzystałem z tabeli EMPLOYEES w schemacie HR. W przypadku tego typu złączenia należy zastosować aliasy w celu rozróżnienia tabel. W klauzuli FROM wymieniłem tabele EMPOYEES dwa razy, każdorazowo nadając jej oddzielny alias. Praktycznie każda osoba w firmie ma swojego przełożonego. Każdy pracownik ma w kolumnie MANAGER_ID EMPLOYEE_ID swojego szefa 😉
Złączeniem tym przyporządkowałem każdemu wierszowi opisującemu pracownika, wiersz z tej samej tabeli opisujący jego przełożonego 🙂
W kolejnej części Darmowego Kursu SQL przyjrzymy się nieco nowszej składni SQL/92.
Część ósma kursu dostępna! Kurs SQL #08: Łączenia w składni SQL/92