Menu Zamknij

🔗 Czym jest JOIN w SQL?

W relacyjnych bazach danych dane są podzielone na wiele tabel, by uniknąć redundancji. JOIN to mechanizm, który pozwala te tabele łączyć w jednym zapytaniu – na podstawie wspólnych kolumn (kluczy).

Definicja: JOIN to klauzula SQL, która łączy wiersze z dwóch lub więcej tabel na podstawie logicznego warunku dopasowania (najczęściej równości klucza głównego z kluczem obcym), tworząc jeden zestaw wynikowy.

Wyobraź sobie sklep internetowy. Tabela Zamówienia przechowuje ID klienta, ale nie jego imię. Żeby wyświetlić „Jan Kowalski zamówił laptopa”, musisz połączyć tabelę zamówień z tabelą klientów – właśnie za pomocą JOIN.

🎯
INNER JOIN
Tylko wiersze, które mają dopasowanie w obu tabelach.
⬅️
LEFT JOIN
Wszystkie wiersze z lewej tabeli + dopasowane z prawej (NULL jeśli brak).
➡️
RIGHT JOIN
Wszystkie wiersze z prawej tabeli + dopasowane z lewej (NULL jeśli brak).
🔄
FULL OUTER JOIN
Wszystkie wiersze z obu tabel – dopasowane i niedopasowane.
✖️
CROSS JOIN
Każdy wiersz z lewej × każdy wiersz z prawej (iloczyn kartezjański).
🪞
SELF JOIN
Tabela łączona z samą sobą – przydatna przy hierarchiach.

📊 Dane przykładowe – nasze tabele

Przez cały artykuł będziemy używać dwóch prostych tabel: Klienci i Zamówienia. Nie każdy klient złożył zamówienie i nie każde zamówienie ma przypisanego klienta.

Tabela: Klienci

KlientIDImieMiasto
1AnnaWarszawa
2BartekKraków
3CelinaGdańsk
4DamianWrocław

Tabela: Zamówienia

ZamówienieIDKlientIDProdukt
1011Laptop
1022Monitor
1032Klawiatura
1045Mysz
💡
Kluczowa obserwacja: Klient ID=3 (Celina) i ID=4 (Damian) nie złożyli żadnego zamówienia. Zamówienie ID=104 należy do KlientID=5, który nie istnieje w tabeli Klienci. Te „luki” doskonale zilustrują różnice między typami JOIN.

Kod SQL – tworzenie tabel

-- Tworzenie tabeli Klienci CREATE TABLE Klienci ( KlientID INT PRIMARY KEY, Imie VARCHAR(50), Miasto VARCHAR(50) ); INSERT INTO Klienci VALUES (1, 'Anna', 'Warszawa'), (2, 'Bartek', 'Kraków'), (3, 'Celina', 'Gdańsk'), (4, 'Damian', 'Wrocław'); -- Tworzenie tabeli Zamówienia CREATE TABLE Zamówienia ( ZamówienieID INT PRIMARY KEY, KlientID INT, Produkt VARCHAR(100) ); INSERT INTO Zamówienia VALUES (101, 1, 'Laptop'), (102, 2, 'Monitor'), (103, 2, 'Klawiatura'), (104, 5, 'Mysz');

🎯 INNER JOIN – część wspólna

Klienci Zamów.
Tylko część wspólna (dopasowane wiersze)

INNER JOIN zwraca wyłącznie te wiersze, dla których wartość klucza istnieje jednocześnie w obu tabelach. To najczęściej używany typ JOIN.

SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci AS k INNER JOIN Zamówienia AS z ON k.KlientID = z.KlientID;

Wynik:

KlientIDImieZamówienieIDProdukt
1Anna101Laptop
2Bartek102Monitor
2Bartek103Klawiatura
⚠️
Celina (ID=3), Damian (ID=4) i zamówienie Myszy (KlientID=5) nie pojawiają się w wyniku – nie mają dopasowania po drugiej stronie. INNER JOIN eliminuje każdy wiersz bez pary.

⬅️ LEFT JOIN – wszystko z lewej tabeli

Klienci Zamów.
Cała lewa tabela + dopasowania z prawej

LEFT JOIN zwraca wszystkie wiersze z lewej tabeli oraz dopasowane wiersze z prawej. Tam, gdzie nie ma dopasowania, pojawia się NULL.

SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci AS k LEFT JOIN Zamówienia AS z ON k.KlientID = z.KlientID;

Wynik:

KlientIDImieZamówienieIDProdukt
1Anna101Laptop
2Bartek102Monitor
2Bartek103Klawiatura
3CelinaNULLNULL
4DamianNULLNULL
Celina i Damian teraz są w wynikach (żółte wiersze) – mimo braku zamówień. Ich kolumny zamówień mają wartość NULL.

Trick – klienci BEZ zamówień

-- Znajdź klientów, którzy NIGDY nic nie zamówili SELECT k.KlientID, k.Imie FROM Klienci AS k LEFT JOIN Zamówienia AS z ON k.KlientID = z.KlientID WHERE z.ZamówienieID IS NULL;
💡
Filtrowanie WHERE prawa_tabela.kolumna IS NULL po LEFT JOIN to klasyczny wzorzec do znajdowania rekordów bez odpowiednika. Używaj go przy audytach danych!

➡️ RIGHT JOIN – wszystko z prawej tabeli

Klienci Zamów.
Cała prawa tabela + dopasowania z lewej

RIGHT JOIN to lustrzane odbicie LEFT JOIN – zwraca wszystkie wiersze z prawej tabeli oraz dopasowane z lewej.

SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci AS k RIGHT JOIN Zamówienia AS z ON k.KlientID = z.KlientID;

Wynik:

KlientIDImieZamówienieIDProdukt
1Anna101Laptop
2Bartek102Monitor
2Bartek103Klawiatura
NULLNULL104Mysz
🔄
W praktyce RIGHT JOIN używa się rzadziej – każde A RIGHT JOIN B można przepisać jako B LEFT JOIN A.

🔄 FULL OUTER JOIN – pełna suma

Klienci Zamów.
Wszystkie wiersze z obu tabel

FULL OUTER JOIN zwraca wszystkie wiersze z obu tabel. Gdzie brak dopasowania – pojawia się NULL.

SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci AS k FULL OUTER JOIN Zamówienia AS z ON k.KlientID = z.KlientID; -- MySQL: emulacja przez UNION SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci k LEFT JOIN Zamówienia z ON k.KlientID = z.KlientID UNION SELECT k.KlientID, k.Imie, z.ZamówienieID, z.Produkt FROM Klienci k RIGHT JOIN Zamówienia z ON k.KlientID = z.KlientID;
💡
FULL OUTER JOIN jest dostępny natywnie w: PostgreSQL, SQL Server, Oracle. W MySQL i MariaDB używaj kombinacji LEFT + RIGHT JOIN z operatorem UNION.

✖️ CROSS JOIN – iloczyn kartezjański

CROSS JOIN łączy każdy wiersz pierwszej tabeli z każdym wierszem drugiej. Nie wymaga warunku ON. 4 × 3 = 12 wierszy.

SELECT k.Imie, p.NazwaProduktu FROM Klienci AS k CROSS JOIN Produkty AS p;
Kiedy użyć? Generowanie kombinacji (kolory × rozmiary), kalendarze, macierze testowe. Ostrożnie przy dużych tabelach – wynik rośnie wykładniczo!

🪞 SELF JOIN – tabela z samą sobą

SELF JOIN to połączenie tabeli z samą sobą za pomocą aliasów. Stosuje się przy strukturach hierarchicznych – np. pracownicy i ich przełożeni.

-- Pracownik + imię jego przełożonego SELECT p.Imie AS Pracownik, szef.Imie AS Przelozony FROM Pracownicy AS p LEFT JOIN Pracownicy AS szef ON p.PrzelozonyID = szef.PracownikID;

📋 Porównanie wszystkich rodzajów JOIN

Typ JOINLewa tabelaPrawa tabelaZastosowanie
INNER JOINTylko dopasowaneTylko dopasowaneRaporty z pewnymi danymi
LEFT JOINWszystkieTylko dopasowaneKlienci z/bez zamówień
RIGHT JOINTylko dopasowaneWszystkieZamówienia z/bez klientów
FULL OUTER JOINWszystkieWszystkieAudyt danych
CROSS JOINWszystkie × WszystkieWszystkie × WszystkieKombinacje, generatory
SELF JOINTabela z sobąTabela z sobąHierarchie, drzewa

🧭 Kiedy używać którego JOIN?

🎯
INNER JOIN – gdy potrzebujesz tylko rekordów z pełnymi danymi z obu stron. Najszybszy. Ideał dla raportów sprzedaży.
⬅️
LEFT JOIN – gdy prawa tabela to dane opcjonalne. Np. lista klientów z ostatnim zamówieniem – nawet jeśli klient nic nie kupił.
➡️
RIGHT JOIN – rzadko stosowany. Zamień kolejność tabel i użyj LEFT JOIN – efekt identyczny, kod czytelniejszy.
🔄
FULL OUTER JOIN – do audytów i reconciliacji. Np. porównanie dwóch systemów – które pozycje są tylko w jednym?
✖️
CROSS JOIN – generowanie kombinacji. Ostrożnie – 1000 × 1000 = milion wierszy!
🪞
SELF JOIN – struktury drzewiaste (organigramy, kategorie). Używaj czytelnych aliasów!
🏆

Zapamiętaj złotą zasadę JOIN

Zacznij od INNER JOIN. Jeśli brakuje Ci wierszy z jednej strony – przejdź na LEFT JOIN. Jeśli z obu stron – użyj FULL OUTER JOIN.

Chcesz nauczyć się SQL od podstaw?

Sprawdź nasz pełny kurs SQL – od SELECT po zaawansowane podzapytania i procedury składowane.

📚 SQL Kurs Podstawowy →

10h | C++ Kurs Podstawowy Programowania | Postaw Na Rozwój

X