Złączenia tabel: INNER JOIN, LEFT JOIN, RIGHT JOIN

INF.03 · teoria
autor: redakcja · 07.09.2026 · aktualizacja: 08.09.2026
Jak połączyć dwie tabele w jednym zapytaniu po kluczu obcym, czym różni się INNER JOIN od LEFT JOIN, co daje iloczyn kartezjański i jak czytać wynik na egzaminie. Lekcja 8.6 kursu INF.03.
Złą­cze­nie (JOIN, czyli POŁĄCZ) to po­łą­cze­nie wier­szy z dwóch tabel po wspól­nej war­to­ści, prawie zawsze po kluczu obcym. Na eg­za­mi­nie pi­sem­nym py­ta­nie po­ka­zu­je dwie tabele i wynik, a trzeba wska­zać za­py­ta­nie, które ten wynik dało. W za­da­niu prak­tycz­nym jedna z czte­rech kwe­rend „wy­ko­rzy­stu­je re­la­cję między ta­be­la­mi", czyli wymaga złą­cze­nia. Po tej lekcji pi­szesz je bez za­glą­da­nia do ściągi.

Dwie tabele i re­la­cja

Baza sklepu z lekcji o SELECT do­sta­je dwie tabele więcej: klien­tów i ich za­mó­wie­nia.
[ TABELE KLIENT I ZAMOWIENIE ]
Tabela klient:
id
imie
miasto
1
Anna
Kraków
2
Piotr
Gdańsk
3
Ewa
Kraków
Tabela zamowienie:
id
klient_id
pro­dukt_id
ilosc
10
1
3
1
11
1
1
2
12
2
5
3
13
NULL
2
1
Ko­lum­na klient_id w tabeli zamowienie to klucz obcy: wska­zu­je na id w tabeli klient. Anna (id 1) ma dwa za­mó­wie­nia, Piotr jedno, Ewa żad­ne­go. Za­mó­wie­nie 13 nie ma klien­ta, na przy­kład był to zakup bez konta. Ta jedna re­la­cja „jeden klient, wiele za­mó­wień" wy­star­czy, żeby zro­zu­mieć wszyst­kie ro­dza­je złą­czeń.

Po co łączyć

Py­ta­nie „kto za­mó­wił mo­ni­tor" wymaga danych z obu tabel: imię jest w klient, numer pro­duk­tu w zamowienie. Bez złą­cze­nia trzeba by dwóch za­py­tań i ręcz­ne­go do­pa­so­wy­wa­nia. Złą­cze­nie robi to w jednym:
SELECT klient.imie, zamowienie.produkt_id FROM klient INNER JOIN zamowienie ON zamowienie.klient_id = klient.id;
Czytaj: weź tabelę klient, dołącz do niej zamowienie, a parą są te wier­sze, w któ­rych klient_id za­mó­wie­nia równa się id klien­ta. ON (NA) mówi, na jakiej pod­sta­wie łączyć. Nazwa tabeli przed kropką mówi, z której tabeli jest ko­lum­na. Gdy nazwa ko­lum­ny nie po­wta­rza się w dru­giej tabeli, przed­ro­stek można po­mi­nąć, ale id jest w obu, więc klient.id trzeba za­pi­sać w ca­ło­ści.
Wynik:
imie
pro­dukt_id
Anna
3
Anna
1
Piotr
5
Anna jest dwa razy, bo ma dwa za­mó­wie­nia. Ewy nie ma wcale. Za­mó­wie­nia 13 też nie ma. To jest wła­śnie cecha złą­cze­nia we­wnętrz­ne­go.

INNER JOIN: tylko do­pa­so­wa­ne pary

INNER JOIN (ZŁĄCZENIE WEWNĘTRZNE) zwraca wy­łącz­nie wier­sze, które mają parę po obu stro­nach. Klient bez za­mó­wień znika, za­mó­wie­nie bez klien­ta znika. Samo słowo JOIN bez przy­miot­ni­ka znaczy w MySQL to samo, co INNER JOIN.
Trzy diagramy kół: INNER JOIN to część wspólna, LEFT JOIN to całe lewe koło, RIGHT JOIN to całe prawe koło

LEFT JOIN: wszyst­ko z lewej

LEFT JOIN (ZŁĄCZENIE LEWE) zwraca wszyst­kie wier­sze tabeli sto­ją­cej po lewej stro­nie słowa JOIN, a z prawej do­pa­so­wa­ne wier­sze albo NULL, gdy pary nie ma.
SELECT klient.imie, zamowienie.id FROM klient LEFT JOIN zamowienie ON zamowienie.klient_id = klient.id;
imie
id
Anna
10
Anna
11
Piotr
12
Ewa
NULL
Ewa jest w wyniku, z NULL za­miast numeru za­mó­wie­nia. Za­mó­wie­nia 13 nadal nie ma, bo lewą tabelą jest klient, a nie zamowienie. Ten wynik od­po­wia­da na py­ta­nie „którzy klien­ci nic nie za­mó­wi­li": wy­star­czy do­pi­sać WHERE zamowienie.id IS NULL.
Zamień LEFT na INNER i po­rów­naj liczbę wier­szy:
[ SQL ]
baza: sklep
zapytanie
103/4000
Otwórz w placu zabaw ›
RIGHT JOIN (ZŁĄCZENIE PRAWE) działa lu­strza­nie: wszyst­ko z prawej tabeli, z lewej para albo NULL. W tym samym za­py­ta­niu z RIGHT JOIN po­ja­wi­ło­by się za­mó­wie­nie 13 z NULL w ko­lum­nie imie, a Ewy by nie było. W prak­ty­ce RIGHT JOIN pisze się rzadko, bo za­mia­na ko­lej­no­ści tabel i LEFT JOIN dają to samo.
Pu­łap­ka: o tym, która tabela jest „lewa", de­cy­du­je miej­sce w za­py­ta­niu, nie ko­lej­ność w wa­run­ku ON. Lewa to ta po FROM, prawa to ta po JOIN.

Złą­cze­nie bez wa­run­ku: ilo­czyn kar­te­zjań­ski

Kiedy za­py­ta­nie łączy tabele bez wa­run­ku, baza paruje KAŻDY wiersz pierw­szej tabeli z KAŻDYM wier­szem dru­giej. To ilo­czyn kar­te­zjań­ski, w SQL także CROSS JOIN (ZŁĄCZENIE KRZYŻOWE).
SELECT klient.imie, zamowienie.id FROM klient, zamowienie;
Trzech klien­tów razy cztery za­mó­wie­nia daje dwa­na­ście wier­szy, w więk­szo­ści bez sensu: Anna z za­mó­wie­niem Piotra, Ewa z każdym za­mó­wie­niem po kolei. Py­ta­nia eg­za­mi­na­cyj­ne lubią to jako ra­chu­nek: tabela z 5 wier­sza­mi i tabela z 8 wier­sza­mi złą­czo­ne bez wa­run­ku dają 40 wier­szy.
Ten sam prze­cin­ko­wy zapis z wa­run­kiem w WHERE daje wynik złą­cze­nia we­wnętrz­ne­go:
SELECT klient.imie, zamowienie.id FROM klient, zamowienie WHERE zamowienie.klient_id = klient.id;
Star­sze py­ta­nia i część ar­ku­szy uży­wa­ją tej formy. Wynik jest iden­tycz­ny z INNER JOIN ... ON, więc obie po­sta­cie trzeba roz­po­zna­wać jako tę samą ope­ra­cję.

Aliasy i trzy tabele

AS skraca nazwy tabel, co przy trzech ta­be­lach ratuje czy­tel­ność. Samo słowo AS można po­mi­nąć i na­pi­sać zamowienie z.
SELECT k.imie, p.nazwa, z.ilosc FROM zamowienie AS z INNER JOIN klient AS k ON z.klient_id = k.id INNER JOIN produkt AS p ON z.produkt_id = p.id;
Każde ko­lej­ne JOIN do­kła­da jedną tabelę i jeden wa­ru­nek ON. Wynik: Anna, Mo­ni­tor 24, 1; Anna, Kla­wia­tu­ra, 2; Piotr, Kabel HDMI, 3. Tak wy­glą­da typowa kwe­ren­da „z wy­ko­rzy­sta­niem re­la­cji" w za­da­niu prak­tycz­nym: tabela po­śred­nia (zamowienie) w środku, dwie tabele słow­ni­ko­we po bokach.

UNION: wyniki jeden pod drugim

UNION (SUMA) to nie złą­cze­nie, ale bywa z nim mylony. Skleja wyniki dwóch za­py­tań w jedną listę wier­szy, jeden pod drugim, i usuwa po­wtó­rze­nia (UNION ALL je zo­sta­wia). Oba za­py­ta­nia muszą zwra­cać tyle samo kolumn tego samego typu.
SELECT miasto FROM klient UNION SELECT miasto FROM dostawca;
JOIN do­kła­da KOLUMNY z dru­giej tabeli obok. UNION do­kła­da WIERSZE pod spodem.

Na eg­za­mi­nie

Py­ta­nie pi­sem­ne po­ka­zu­je dwie tabele po trzy, cztery wier­sze i tabelę wy­ni­ko­wą. Metoda: policz wier­sze wyniku i sprawdź, czy są w nim NULL. Tyle wier­szy, ile do­pa­so­wa­nych par, i bez NULL: INNER JOIN. Wszyst­kie wier­sze lewej tabeli i NULL po prawej: LEFT JOIN. Liczba wier­szy równa ilo­czy­no­wi liczb wier­szy: brak wa­run­ku. Druga rzecz do spraw­dze­nia to sam wa­ru­nek ON: klucz obcy jednej tabeli musi być po­rów­na­ny z klu­czem głów­nym dru­giej. ON klient.id = zamowienie.id po­rów­nu­je dwa nie­zwią­za­ne numery i jest błędną od­po­wie­dzią, która na pierw­szy rzut oka wy­glą­da po­praw­nie.
W za­da­niu prak­tycz­nym arkusz opi­su­je kwe­ren­dę sło­wa­mi, na przy­kład „wy­pi­su­je imiona klien­tów i nazwy za­mó­wio­nych pro­duk­tów". Każda wy­mie­nio­na ko­lum­na wska­zu­je tabelę, a droga między ta­be­la­mi idzie po klu­czach obcych ze sche­ma­tu po­da­ne­go w ar­ku­szu. Kwe­ren­dę zapisz w kwerendy.txt do­kład­nie w tej po­sta­ci, którą wy­ko­na­łeś, ze śred­ni­kiem na końcu.

Ściąga

Zapis
Co zwraca
A INNER JOIN B ON warunek
tylko pary speł­nia­ją­ce wa­ru­nek
A JOIN B ON warunek
to samo, co INNER JOIN
A LEFT JOIN B ON warunek
wszyst­kie wier­sze A, z B para albo NULL
A RIGHT JOIN B ON warunek
wszyst­kie wier­sze B, z A para albo NULL
FROM A, B bez wa­run­ku
ilo­czyn kar­te­zjań­ski: każdy z każdym
FROM A, B WHERE a.x = b.y
jak INNER JOIN
tabela.kolumna
ko­lum­na z kon­kret­nej tabeli; ko­niecz­ne, gdy nazwa się po­wta­rza
tabela AS t
alias, krót­sza nazwa tabeli w za­py­ta­niu
SELECT ... UNION SELECT ...
wier­sze dwóch za­py­tań jeden pod drugim, bez po­wtó­rzeń
Pobierz ściągę PDF
ZAWODNIK
egzamin zawodowy INF.02 · INF.03 · INF.04
Serwer Discord
Egzaminy zawodowe IT/Matury/Studia
@yastor
© 2026 Zawodnik · by Yastor
Arkusze i zasady oceniania pochodzą z CKE. Serwis nie jest powiązany z Centralną Komisją Egzaminacyjną.