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 tuCustomerIDiShipperID.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.Kolumnadla przejrzystości.FROM (Orders INNER JOIN Customers ON ...)– Zaczynamy od połączenia, które już znamy. Bierzemy tabelęOrdersi 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 ...– TabelaCustomersjest 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
OrderDatezobaczysz 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 ORDER 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