Wstęp: Od prostych par do złożonej sieci powiązań
Witaj ponownie. W poprzednich lekcjach nauczyliśmy się zaglądać do jednego „segregatora” (SELECT ... FROM
), filtrować jego zawartość (WHERE
) i łączyć informacje z dwóch różnych segregatorów (INNER JOIN
). Dziś staniemy się prawdziwymi detektywami danych.
Nasze zadanie będzie wymagało połącznia informacji nie z dwóch, a z trzech różnych miejsc. A kiedy już zbierzemy wszystkie poszlaki, nauczymy się je układać w logicznym porządku, tak aby opowiedziały nam klarowną historię. W karate precyzyjny ruch jest ważny, ale dopiero połączenie kilku ruchów w płynną, logiczną sekwencję (kata) pokazuje prawdziwe mistrzostwo. Zaczynajmy nasze „kata” z danymi.
Część 1: Łączymy trzy tabele – Pełen obraz zamówienia
Wyobraź sobie, że chcemy stworzyć raport, który pokaże nam listę zamówień, ale dla każdego zamówienia chcemy widzieć dwie kluczowe informacje:
- Pełną nazwę klienta, który złożył zamówienie.
- Nazwę firmy spedycyjnej, która to zamówienie dostarczyła.
Jeśli zajrzymy do naszego narzędzia SQL Tryit Editor, zobaczymy, że potrzebujemy aż trzech tabel:
Orders
(Zamówienia) – tu jest serce operacji, mamy tuCustomerID
iShipperID
.Customers
(Klienci) – stąd weźmiemy nazwę klienta (CustomerName
) na podstawieCustomerID
.Shippers
(Spedytorzy) – stąd weźmiemy nazwę firmy (ShipperName
) na podstawieShipperID
.
Nasza tabela Orders
jest centralnym punktem, który łączy pozostałe dwie. Musimy więc wykonać dwa połączenia: najpierw dołączymy Klientów do Zamówień, a potem do tego wyniku dołączymy Spedytorów.
W dialekcie MS Access, którego używa nasze narzędzie, kluczowe jest użycie nawiasów do grupowania połączeń.
SQL
SELECT
Orders.OrderID,
Customers.CustomerName,
Shippers.ShipperName
FROM
(Orders
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID)
INNER JOIN Shippers ON Orders.ShipperID = Shippers.ShipperID;

Rozłóżmy to na spokojnie:
SELECT Orders.OrderID, Customers.CustomerName, Shippers.ShipperName
– Wybieramy konkretne kolumny, które nas interesują. Używamy notacjiTabela.Kolumna
dla przejrzystości.FROM (Orders INNER JOIN Customers ON ...)
– Zaczynamy od połączenia, które już znamy. Bierzemy tabelęOrders
i dołączamy do niejCustomers
. Zamykamy to w nawias, tworząc wirtualną, połączoną tabelę.INNER JOIN Shippers ON ...
– Do wyniku pierwszego połączenia (które jest w nawiasach), dołączamy kolejną tabelę –Shippers
. Kluczem jest tym razemShipperID
.
Uruchom ten kod. Zobacz, jak pięknie dane z trzech różnych źródeł połączyły się w jeden, czytelny raport!
WAŻNA UWAGA
Jak poprzednio pisałem, udostępniony przez W3Schools edytor jest uproszczony, i SQL nie jest full standardowy. W powyższym przypadku mamy nawiasy (Orders inner join …
W „normalnych” środowiskach ten nawias nie jest potrzebny (tak jak słowo inner, ale niedługo zaczniemy tworzyć bąze danych u was na komputerze za pomocą darmowych i prostych narzędzi, wtedy zobaczycie:)
Część 2: LEFT JOIN
– A co z tymi, którzy nic nie zamówili?
INNER JOIN
, którego użyliśmy, działa jak bramkarz na imprezie dla par. Wpuszcza tylko te osoby, które mają partnera w drugiej tabeli. Pokazuje tylko te zamówienia, które mają i klienta, i spedytora.
Ale co, jeśli chcemy stworzyć listę wszystkich naszych klientów i sprawdzić, kto z nich złożył zamówienie, a kto nie?
Tu właśnie wkracza LEFT JOIN
. Działa on inaczej. Mówi: „Pokaż mi wszystkie wiersze z lewej tabeli (tej wymienionej jako pierwsza), a z prawej dołącz pasujące dane. Jeśli w prawej tabeli nie ma dopasowania, zostaw tam puste miejsce (NULL
)”.
Stwórzmy listę wszystkich klientów i zobaczmy daty ich zamówień.
SQL
SELECT Customers.CustomerName, Orders.OrderDate
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID;

Co tu się stało?
FROM Customers LEFT JOIN Orders ...
– TabelaCustomer
s
jest teraz naszą tabelą „po lewej„. Oznacza to, że SQL weźmie każdego klienta z tej tabeli, bez wyjątku.- Następnie spróbuje dołączyć datę zamówienia z tabeli
Orders
. - Jeśli klient złożył jakieś zamówienia, zobaczysz jego nazwę powieloną tyle razy, ile zamówień złożył, z odpowiednimi datami.
Zobacz, na zrzucie ekranu widać, ze Berglunds snabbköp złożył trzy zamówienia. - Jeśli klient nigdy nic nie zamówił, jego nazwa i tak pojawi się na liście, ale w kolumnie
OrderDate
zobaczysz wartośćNULL
, czyli „brak danych”.
LEFT JOIN
jest bezcenny, gdy chcesz znaleźć brakujące dane lub zobaczyć pełen obraz, a nie tylko pasujące do siebie elementy.
Część 3: ORDER BY
– zaprowadzamy porządek
Domyślnie baza danych zwraca wyniki w kolejności, która jest dla niej najwygodniejsza – często bez żadnego logicznego porządku. My jednak chcemy, aby nasze raporty były czytelne. Do sortowania wyników służy klauzula ORDER BY
, którą zawsze umieszczamy na samym końcu zapytania.
Weźmy naszą listę wszystkich klientów i ich zamówień i posortujmy ją alfabetycznie po nazwie klienta.
SQL
SELECT Customers.CustomerName, Orders.OrderDate
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerName;
Domyślnie O
RDER BY
sortuje rosnąco (od A do Z, od 1 do 100). To samo uzyskalibyśmy pisząc ORDER BY Customers.CustomerName ASC
(od ang. ascending).
A co, jeśli chcemy posortować od końca? Na przykład od najnowszych zamówień do najstarszych? Używamy słowa kluczowego DESC
(od ang. descending).
SQL
SELECT Customers.CustomerName, Orders.OrderDate
FROM Customers
INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
ORDER BY Orders.OrderDate DESC;
Uwaga: wróciłem tu do INNER JOIN
, aby nie sortować pustych (NULL
) wartości dla klientów bez zamówień.
Podsumowanie i Twoje zadanie
To była intensywna lekcja! Opanowałeś dziś trzy kluczowe koncepcje:
- Łączenie danych z trzech tabel, by uzyskać pełny obraz.
- Używanie
LEFT JOIN
, by znaleźć też te dane, które nie mają swojego odpowiednika w drugiej tabeli. Czyli z pierwszej tabeli bierze wszystkie rekordy a z drugiej tylko pasujące. - Sortowanie wyników za pomocą
ORDER BY
, by były czytelne i uporządkowane. DESC gdy chcemy od najnowszych, gdy sortujemy po dacie albo najdroższych jeśli sortujemy po cenie.
Twoje zadanie na dziś: Napisz zapytanie, które wyświetli nazwę każdego produktu (ProductName
) oraz nazwę firmy (SupplierName
), która go dostarcza. Lista musi zawierać również te produkty, które (teoretycznie) nie mają przypisanego dostawcy. Są w ogóle tacy?
Posortuj wyniki alfabetycznie po nazwie produktu.
Potrzebne tabele to Products
i Suppliers
. Daj znać w komentarzach, jak Ci poszło!
Co będzie dalej?
Powoli mam dość W3Schools i tego prostego narzędzia, czas na bazę na twoim komputerze! (choć dalej uproszczoną) Użyjemy plikowej bazy SQLite oraz aplikacji HeidiSQL. Oba narzędzia są darmowe, i można w nich spokojnie przećwiczyć większość możliwości SQLa.
Do przeczytania!
OK, czekam na więcej