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.

Ćwicz to