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

kajodata.com 10 miesięcy temu

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, iż FULL JOIN oraz SELF JOIN to potężne narzędzia, które naprawdę warto mieć w swoim analitycznym arsenale. jeżeli 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ę, iż 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.

Opanuj SQL z moim kursem!

Poznasz zarówno podstawy, jak i zaawansowane zapytania analityczne (CTE, subqueries, window functions). Nauczysz się pracować na różnych silnikach – na kursie pracujemy zarówno na MySQL, jak i na Postgres. Wszystko zainstalujemy na Twoim komputerze, plus dostaniesz mnóstwo zestawów danych do ćwiczeń.

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, iż ż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żeli 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

Zgadzam się na przetwarzanie moich danych osobowych przez KajoData Kajo Rudziński w celu realizacji usługi newsletter, a tym samym wysyłania mi informacji o produktach blogowych, usługach, lub nowościach, zgodnie z polityką prywatności. Wiem, iż zgodę tę mogę w każdej chwili cofnąć.
Zapisuję się Loading...

Dzięki! To nie koniec...

...pamiętaj, by teraz wejść na maila i potwierdzić subskrybcję 🙂 Jeżeli nic nie doszło, to sprawdź skrzynkę ze spamem.
* * * Gdy potwierdzisz newsletter, dostaniesz ostateczne potwierdzenie i obiecane prezenty w kolejnym mailu 🙂

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ę, iż ten artykuł pomógł Ci zobaczyć te złączenia w praktycznym, a nie podręcznikowym świetle. jeżeli uznasz, iż może pomóc komuś innemu, będzie mi bardzo miło, jeżeli udostępnisz go dalej w swoich mediach społecznościowych.

Inne interesujące artykuły:

  • Jak sprawdzam poprawność danych w Excelu: praktyczna lekcja z ISNUMBER i AND
  • KajoDataSpace: najlepsze miejsce, żeby naprawdę wejść w świat analizy danych
  • Myślisz, iż analityk tylko klepie raporty? Zobacz, gdzie naprawdę zaczyna się jego rola
  • Czekasz, aż poczujesz się gotowa do aplikowania? Ten moment może nie nadejść
  • Czujesz, iż jesteś 10 kroków za innymi? To tylko złudzenie

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ż, iż 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

Idź do oryginalnego materiału