Kurs SQL #07: Łączenie wielu tabel i typy złączeń

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

eBook Niezbędnik Administratora Baz Danych cover

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_NAMECUST_LAST_NAMEORDER_MODEQUANTITYLIST_PRICE
HarrisonSutherlanddirect5316
HarrisonSutherlanddirect4781
HarrisonSutherlanddirect4746
HarrisonSutherlanddirect4821

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_IDPRODUCT_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 😉

kurs sql złączenia typy inner outer join
Typy złączeń

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


🔥Kurs Administracji PostgreSQL w promocji -70%!🔥