Jak działa FULL JOIN i SELF JOIN w SQL? Pełne wyjaśnienie na przykładach z życia analityka

21 listopada 2025

full join i self join w sql - łączenie tabel w sql

Przez ostatnie lata pracy jako analityk i architekt danych widziałem dziesiątki sytuacji, w których FULL JOIN i SELF JOIN ratowały skórę projektom, raportom czy analizom. A mimo to są to jedne z tych rodzajów złączeń, które początkujący SQL-owcy poznają dopiero po czasie — często unikając ich, bo „inne joiny wystarczą”.

W tej lekcji pokażę Ci jednak krok po kroku, że FULL JOIN oraz SELF JOIN to potężne narzędzia, które naprawdę warto mieć w swoim analitycznym arsenale. Jeśli znasz już podstawy — SELECT, JOIN, GROUP BY — to ta lekcja będzie naturalnym rozszerzeniem Twoich umiejętności.

Nie będę Ci opowiadał definicji z podręczników. Przejdziemy przez realne przykłady, dokładnie takie, jakie przerabiamy w moim kursie SQL. I pokażę Ci przede wszystkim, dlaczego te JOIN-y są w praktyce tak przydatne.


Dlaczego FULL JOIN i SELF JOIN w ogóle istnieją?

Zacznijmy od spojrzenia z lotu ptaka.

Inner JOIN

Zwraca część wspólną dwóch tabel.

LEFT JOIN

Zwraca wszystkie rekordy z lewej tabeli i tylko dopasowane z prawej.

RIGHT JOIN

Odwrotność LEFT JOIN — wszystko z prawej, dopasowania z lewej.

No i teraz logiczne pytanie:
skoro mam LEFT JOIN i RIGHT JOIN, to czy nie dałoby się ich po prostu połączyć i dostać wszystko?

Dałoby się. I właśnie to robi FULL JOIN.

Analogicznie:

SELF JOIN powstał z innej potrzeby:
czasem musimy połączyć tabelę… z samą sobą.
Brzmi abstrakcyjnie, ale zobaczysz za chwilę, że w praktycznych analizach to wcale nie jest takie dziwne.


FULL JOIN – łączenie dwóch światów naraz

W MySQL FULL JOIN nie działa. To znaczy: da się go zasymulować, ale natywnie baza go nie wspiera. Natomiast PostgreSQL, którego używam w kursie, radzi sobie z nim doskonale. I dzięki temu mogę Ci pokazać czysty przykład, bez kombinowania.

Żeby FULL JOIN miał sens, musimy przygotować dane. Potrzebujemy dwóch tabel, w których:

  • część rekordów występuje w obu tabelach,
  • część rekordów jest tylko w jednej,
  • część tylko w drugiej.

Wtedy zobaczysz pełną moc tego złączenia.

W moim przykładzie korzystam z tabel:

  • orders (zamówienia),
  • order_returns (zwroty zamówień).

Ale specjalnie dodaję jedno zamówienie, które istnieje tylko w tabeli zwrotów, a nie ma go w orders. To pozwala pokazać Ci różnicę między rodzajami joinów.

Dodanie specjalnego rekordu

INSERT INTO order_returns (order_id, reason, amount)
VALUES (999, 'test', 0);

Po dodaniu tego rekordu mamy sytuację:

  • zamówienie 999 istnieje w order_returns,
  • ale nie istnieje w orders.

A więc FULL JOIN powinien je zwrócić — z jednej strony z danymi, z drugiej ze wszystkimi NULL-ami.


Budujemy FULL JOIN – krok po kroku

Załóżmy najpierw najprostszy wariant:

SELECT
    o.order_id AS order_from_orders,
    r.order_id AS order_from_returns
FROM orders o
FULL OUTER JOIN order_returns r
    ON o.order_id = r.order_id;

Co tu się dzieje?

SQL przechodzi przez obie tabele i:

  • bierze wszystkie dopasowania (jak przy INNER JOIN),
  • bierze wszystkie rekordy z lewej, które nie mają dopasowania (jak LEFT JOIN),
  • bierze wszystkie rekordy z prawej, które nie mają dopasowania (jak RIGHT JOIN).

Czyli w praktyce:

FULL JOIN = LEFT JOIN + RIGHT JOIN

Pokażę Ci jak to wygląda w wynikach:

  • Na początku zobaczysz rekordy, które pasują po obu stronach.
  • Potem te, które są tylko w jednej tabeli.
  • A na końcu rekordy tylko z drugiej tabeli — z kolumnami z drugiej strony ustawionymi na NULL.

W mojej lekcji, gdy sortuję wyniki według jednej kolumny, widać to bardzo wyraźnie. Na przykład:

  1. Wyniki wspólne — order_id istnieje w obu tabelach.
  2. Rekord z order_returns, którego nie ma w orders — np. 999.
  3. Rekordy z orders, których nie ma w returns — z wartościami NULL po stronie returns.

To jest właśnie pełny obraz danych — FULL VIEW.


Sortowanie, żeby zobaczyć pełny obraz

W lekcji robię jeszcze jedną rzecz, która wizualnie pomaga zrozumieć kolejność.

ORDER BY order_from_returns DESC;

Po takim sortowaniu:

  • najpierw pojawiają się puste pola (NULL),
  • potem rekordy uporządkowane po stronie returns.

A gdy sortujesz odwrotnie:

  • najpierw rekordy wspólne,
  • potem ordery, które są tylko w jednej tabeli.

To świetnie pokazuje, jak FULL JOIN „dokleja” dane z obu światów.


Kiedy FULL JOIN jest naprawdę przydatny?

Z mojego doświadczenia FULL JOIN jest jak zdjęcie panoramiczne — nie do codziennego użytku, ale czasem niesamowicie potrzebne.

Kiedy go używam:

  1. Łączenie systemów źródłowych
    Gdy dane są niekompletne lub niespójne po obu stronach.
  2. Analiza migracji
    W jednej tabeli stare dane, w drugiej nowe — FULL JOIN pokazuje, co się zgadza, a co nie.
  3. Porównywanie danych z dwóch raportów
    Zwłaszcza gdy raporty nie są identyczne.
  4. Debugowanie ETL
    FULL JOIN błyskawicznie pokazuje, czego nie udało się przetworzyć.
  5. Analiza różnic w zwrotach, płatnościach, refundacjach
    Idealny przykład to właśnie orders vs order_returns.

W codziennych zadaniach analitycznych FULL JOIN jest trochę jak narzędzie, którego nie używasz często — ale kiedy już przychodzi moment, w którym jest potrzebne, to naprawdę robi robotę.


Przejdźmy do SELF JOIN – łączenia tabeli z samą sobą

SELF JOIN brzmi na początku jak sztuczka matematyczna: „Połącz tabelę ze sobą”. Ale w praktyce to jedno z najbardziej intuicyjnych narzędzi do pracy ze strukturami drzewiastymi, hierarchiami, zależnościami.

Wyobraź sobie:

  • Tabelę pracowników.
  • W niej pracownik ma manager_id.
  • Ten manager_id wskazuje na innego pracownika z tej samej tabeli.

I już wiesz, że żeby to połączyć, musisz użyć… tej samej tabeli.


Tworzymy prostą tabelę pracowników

W lekcji tworzę tabelę employees (pisownia może wyglądać dziwnie, bo w napisach była automatyczna transkrypcja). Przykład:

CREATE TABLE employees (
    id INT,
    manager_id INT
);

Dodajmy kilka rekordów:

INSERT INTO employees VALUES
(1, NULL),
(2, 1),
(3, 1),
(4, 2);

Teraz struktura wygląda tak:

idmanager_id
1NULL
21
31
42

Czyli:

  • Pracownik 1 nie ma managera.
  • Pracownicy 2 i 3 raportują do pracownika 1.
  • Pracownik 4 raportuje do pracownika 2.

Naturalna hierarchia.


SELF JOIN – połączenie tabela + tabela

Żeby dowiedzieć się, kto jest czyim szefem, łączymy tabelę employees z samą sobą:

SELECT
    e1.id   AS boss,
    e2.id   AS employee
FROM employees e1
JOIN employees e2
    ON e1.id = e2.manager_id;

Co tu się dzieje?

  • e1 — alias dla tabeli, którą potraktujemy jako przechowującą szefów,
  • e2 — alias dla tabeli, którą potraktujemy jako podwładnych.

JOIN łączymy po warunku:

e1.id = e2.manager_id

Czyli:

„Znajdź mi pracowników, dla których dany id jest ich managerem”.

Wynik:

bossemployee
12
13
24

I to dokładnie odpowiada naszej hierarchii.


Dodanie LEFT JOIN, żeby zobaczyć pełny obraz

A jeśli chcemy zobaczyć także tych, którzy nie mają podwładnych — np. pracownika 3 i pracownika 4 — stosujemy:

SELECT
    e1.id   AS boss,
    e2.id   AS employee
FROM employees e1
LEFT JOIN employees e2
    ON e1.id = e2.manager_id;

Wtedy dostaniemy:

bossemployee
12
13
24
3NULL
4NULL

To idealnie pokazuje strukturę całej organizacji.


SELF JOIN – gdzie używam go najczęściej?

Ten rodzaj złączenia jest świetny, kiedy:

1. Pracujesz z hierarchiami

Struktury organizacyjne, kategorie produktów, wersje dokumentów, drzewka zależności.

2. Chcesz znaleźć powiązania w ramach tej samej encji

Np. który produkt jest poprzednią wersją innego produktu.

3. Budujesz widok nadrzędnych i podrzędnych elementów

Tak jak manager → pracownik.

4. Rozwiązujesz zadania rekrutacyjne

SELF JOIN to klasyka w zadaniach SQL na rozmowach o pracę.

5. Tworzysz analizę zmian statusów

Np. zamówienie → poprzedni status → kolejny status.


FULL JOIN vs SELF JOIN – nie myl ich ze sobą

Choć nazwy brzmią podobnie, służą do zupełnie innych rzeczy:

JOINOpisTypowe zastosowanie
FULL JOINŁączy dwie różne tabele tak, aby pokazać wszystko z obuporównywanie danych, migracje, debugowanie ETL
SELF JOINŁączy tabelę z samą sobąhierarchie, relacje wewnętrzne

Jeśli pamiętasz tę jedną zasadę, łatwiej Ci będzie zdecydować, kiedy którego użyć.

Zapisz się do
newslettera

🎁 i zgarnij darmowe bonusy:

Poradnik Początkującego Analityka

Video - jak szukać pracy w IT

Regularne dawki darmowej wiedzy, bez spamu


Podsumowanie – jak wykorzystasz to w praktyce?

Chcę, żebyś po tej lekcji miał jasność:

  • FULL JOIN daje Ci kompletny obraz danych między dwiema tabelami.
    Widzi wszystko — dopasowane i niedopasowane rekordy.
    Jest idealny do analiz, porównań, migracji, debugowania.
  • SELF JOIN pozwala zbudować relacje w obrębie jednej tabeli.
    Dzięki aliasom możesz analizować hierarchie, powiązania i zależności.

Jeśli pracujesz z SQL-em na co dzień lub jesteś w trakcie nauki do przebranżowienia, te dwa joiny prędzej czy później pojawią się w Twojej pracy. I będą od Ciebie wymagały nie tylko zapamiętania składni, ale przede wszystkim zrozumienia logiki, która za nimi stoi.

Mam nadzieję, że ten artykuł pomógł Ci zobaczyć te złączenia w praktycznym, a nie podręcznikowym świetle. Jeśli uznasz, że może pomóc komuś innemu, będzie mi bardzo miło, jeśli udostępnisz go dalej w swoich mediach społecznościowych.

Inne ciekawe artykuły:

Autorem artykułu jest Kajo Rudziński – analytical data architect, uznany ekspert w analizie danych, twórca KajoData oraz społeczności dla analityków KajoDataSpace.

To tyle w tym temacie. Analizujcie w pokoju!  

Podobał Ci się ten artykuł 🙂?
Podziel się nim w Social Mediach 📱
>>> udostępnij go na LinkedIn i pokaż, że codziennie uczysz się czegoś nowego 
>>> wrzuć go na Facebooka, to się może przydać któremuś z Twoich znajomych 
>>> Przypnij sobie tą stronkę to zakładek, może się przydać w przyszłości

Wolisz oglądać 📺 niż czytać – nie ma problemu
>>> Obserwuj i oglądaj KajoData na YouTube

Ja Ci ją z przyjemnością wyślę. Za darmo. Bez spamu.

Poradnik Początkującego Analityka

Video - jak szukać pracy w IT

Regularne dawki darmowej wiedzy, bez spamu.