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.
⭐Zostań Administratorem Baz Danych! ⭐
Kompleksowy kurs z moim wsparciem: Praktyczna Administracja Oracle Database!
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