Złączenia w SQL wyjaśnione, z jednym przykładem każdego
Złączenie łączy wiersze z dwóch tabel przez dopasowanie kolumny. Rodzaj złączenia decyduje, co się stanie z wierszami, które nie mają pary. Wszystkie przykłady używają bazy piekarni: 8 klientów i 12 zamówień, z czego dwa to zamówienia bez klienta (walk-in).
INNER JOIN: tylko dopasowania
Zachowuje wiersz tylko wtedy, gdy po obu stronach jest dopasowanie. Klienci bez zamówień i zamówienia bez klienta znikają.
SELECT c.last_name, o.order_id FROM customers AS c INNER JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id;
Wynik: 10 wierszy: zamówienia należące do klientów.
LEFT JOIN: zachowaj wszystko po lewej
Zachowuje każdy wiersz lewej tabeli. Tam, gdzie prawa tabela nie ma dopasowania, jej kolumny są NULL. Filtrowanie przez IS NULL znajduje wiersze bez dopasowania.
SELECT c.last_name, COUNT(o.order_id) AS orders FROM customers AS c LEFT JOIN orders AS o ON o.customer_id = c.customer_id GROUP BY c.customer_id, c.last_name ORDER BY c.customer_id;
Wynik: Wszystkich 8 klientów; Kim i Meyer mają po 0 zamówień.
RIGHT JOIN: zachowaj wszystko po prawej
Lustrzane odbicie LEFT JOIN. Większość osób zamienia kolejność tabel i używa LEFT JOIN, bo tak czyta się to naturalniej.
SELECT o.order_id, c.last_name FROM customers AS c RIGHT JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id;
Wynik: Wszystkie 12 zamówień; zamówienia 4 i 11 mają NULL w nazwisku (walk-in).
FULL JOIN: zachowaj wszystko po obu stronach
Zachowuje niedopasowane wiersze z obu tabel. Przydaje się do porównania dwóch list i sprawdzenia, czego brakuje po każdej stronie.
SELECT c.last_name, o.order_id FROM customers AS c FULL JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id, c.last_name;
Wynik: 14 wierszy: 10 dopasowań, 2 zamówienia walk-in i klienci Kim i Meyer bez zamówienia.
CROSS JOIN: każda kombinacja
Łączy każdy wiersz pierwszej tabeli z każdym wierszem drugiej. Liczba wierszy to iloczyn obu liczb. Używaj tego świadomie, na przykład do zbudowania siatki dat i kategorii.
SELECT COUNT(*) AS combinations FROM customers CROSS JOIN products;
Wynik: 72, czyli 8 klientów razy 9 produktów.
Self join: tabela złączona sama ze sobą
Nadaj tej samej tabeli dwa aliasy, aby porównać wiersze w jednej tabeli, na przykład dwóch klientów z tego samego miasta.
SELECT a.first_name AS first_customer, b.first_name AS second_customer, a.city FROM customers AS a JOIN customers AS b ON a.city = b.city AND a.customer_id < b.customer_id ORDER BY a.city;
Wynik: Pary Emma i Hugo (Berlin), Ben i Dev (London) oraz Chloe i Farid (Paris).
Częste pytania
- Dlaczego moje złączenie zwraca więcej wierszy, niż się spodziewam?
- Zwykle kolumna łącząca nie jest unikalna po jednej stronie, więc każdy wiersz pasuje do kilku wierszy. Sprawdź klucze i policz wiersze przed złączeniem i po nim.
- Czy ma znaczenie, czy warunek jest w ON, czy w WHERE?
- Dla INNER JOIN nie ma różnicy. Dla LEFT JOIN warunek na prawej tabeli w WHERE usuwa niedopasowane wiersze i zamienia LEFT JOIN w INNER JOIN. Umieść go w ON, aby je zachować.
- Które złączenie działa tak jak VLOOKUP?
- LEFT JOIN: każdy wiersz głównej tabeli zostaje, a kolumna wyszukiwania jest NULL tam, gdzie nic nie pasuje, jak #N/A. W przeciwieństwie do VLOOKUP zwraca wszystkie dopasowania, a nie tylko pierwsze.