Menu Zamknij
Bazy danych · SQL · Łączenie tabel

JOIN w SQL – jak łączyć tabele?

Poznaj INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN i SELF JOIN. Zobacz zapytania oraz wyniki na przykładzie klientów i zamówień.

🔗 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

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:

KlientIDImie Zamó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

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:

KlientIDImie ZamówienieIDProdukt
1Anna101Laptop
2Bartek102Monitor
2Bartek103Klawiatura
3Celina NULLNULL
4Damian NULLNULL
✅
Celina i Damian teraz są w wynikach (wyróżnione 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

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:

KlientIDImie ZamówienieIDProdukt
1Anna101Laptop
2Bartek102Monitor
2Bartek103Klawiatura
NULLNULL 104Mysz
🔄
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

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 JOIN Lewa tabela Prawa tabela Zastosowanie
INNER JOIN Tylko dopasowane Tylko dopasowane Raporty z pewnymi danymi
LEFT JOIN Wszystkie Tylko dopasowane Klienci z/bez zamówień
RIGHT JOIN Tylko dopasowane Wszystkie Zamówienia z/bez klientów
FULL OUTER JOIN Wszystkie Wszystkie Audyt danych
CROSS JOIN Wszystkie × Wszystkie Wszystkie × Wszystkie Kombinacje, generatory
SELF JOIN Tabela 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 →

Przeczytaj również

Ładowanie artykułów…

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

X