0Pricing
Coding Interview Prep · Lekcja

SELF JOIN dla hierarchii

Łączenie tabeli z samą sobą w celu modelowania relacji pracownik–przełożony i rodzic–dziecko

SELF JOIN dla hierarchii to bezpłatna lekcja Coding Interview Prep na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Coding Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Czym naprawdę jest SELF JOIN

Self join to po prostu złączenie, w którym ta sama tabela występuje po obu stronach. Nie istnieje specjalne słowo kluczowe SELF JOIN; należy napisać zwykłe INNER lub LEFT JOIN i odwołać się dwukrotnie do tej samej tabeli.

Elementem, który umożliwia takie złączenie, są aliasy tabel. Każdej kopii nadaje się inny alias, aby silnik traktował je jak dwie niezależne tabele.

SELECT e.name, m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;

Dlaczego aliasy są konieczne

Bez różnych aliasów zapytanie jest niejednoznaczne: każda nazwa kolumny występuje dwukrotnie, więc silnik nie wie, o którą kopię chodzi. Nadanie aliasu każdej instancji rozwiązuje ten problem.

To złączenie należy odczytywać jako: 'połącz każdy wiersz pracownika z wierszem pracownika, który jest jego menedżerem'. Alias e oznacza pracownika, m menedżera, a oba wiersze pochodzą z tej samej fizycznej tabeli.

-- e = the employee, m = that employee's manager
SELECT e.id, e.name, m.name AS reports_to
FROM employees AS e
JOIN employees AS m ON e.manager_id = m.id;

Model pracownik–menedżer

Klasycznym scenariuszem dla self join jest lista sąsiedztwa: pojedyncza tabela przechowuje wiersze, a każdy wiersz wskazuje element nadrzędny za pomocą klucza obcego odwołującego się do tej samej tabeli.

Tabela employees z kolumną manager_id odwołującą się do employees.id modeluje całą strukturę organizacyjną w jednej tabeli. Każdy menedżer jest po prostu kolejnym wierszem pracownika.

-- One table holds the whole hierarchy
-- employees(id, name, manager_id)
-- manager_id -> employees.id

Wyświetlanie wszystkich pracowników wraz z menedżerami

Najczęściej zadawane pytanie dotyczące self join: wyświetlić każdego pracownika obok nazwiska jego menedżera. Należy połączyć kopię pracowników z kopią menedżerów według warunku e.manager_id = m.id.

Zwraca to jeden wiersz dla każdego pracownika, którego menedżer istnieje. Należy zauważyć, że najwyżej położona osoba w strukturze, czyli dyrektor generalny, ma wartość NULL w manager_id i zostanie pominięta przez złączenie wewnętrzne.

SELECT e.name AS employee, m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;

LEFT JOIN, aby zachować korzeń drzewa

Aby uwzględnić dyrektora generalnego, którego manager_id ma wartość NULL, należy użyć LEFT JOIN. Strona pracowników zostaje zachowana, a kolumny menedżera przyjmują wartość NULL dla wierszy bez elementu nadrzędnego.

Rekruterzy wykorzystują to pytanie, aby sprawdzić, czy pamiętają Państwo, że wewnętrzny self join usuwa węzły główne. Rozwiązanie jest takie samo jak w każdej sytuacji związanej ze złączeniem zewnętrznym, gdy należy zachować niedopasowane wiersze.

SELECT e.name AS employee,
       COALESCE(m.name, '(top level)') AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

Zliczanie bezpośrednich podwładnych każdego menedżera

Częste pytanie uzupełniające brzmi: ile osób podlega bezpośrednio każdemu menedżerowi? Należy wykonać self join, a następnie pogrupować dane według menedżera.

Łączymy pracowników z menedżerami, grupujemy według tożsamości menedżera i zliczamy pracowników. Zliczani są tylko bezpośredni podwładni, a nie całe poddrzewo znajdujące się poniżej danego menedżera.

SELECT m.name AS manager, COUNT(*) AS direct_reports
FROM employees e
JOIN employees m ON e.manager_id = m.id
GROUP BY m.id, m.name
ORDER BY direct_reports DESC;

Przejście o dwa poziomy w głąb

Aby uzyskać pracownika, jego menedżera oraz menedżera tego menedżera, należy połączyć trzy kopie tabeli. Każdy poziom oznacza kolejne self join.

To rozwiązanie działa dla ustalonej, znanej głębokości. Jeśli potrzebna jest dowolna głębokość, self join nie wystarczy — jest to sygnał, aby użyć rekursywnego CTE, o którym rekruterzy oczekują, że Państwo wspomną.

SELECT e.name AS employee,
       m.name AS manager,
       g.name AS grand_manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
LEFT JOIN employees g ON m.manager_id = g.id;

Self join a rekursywne CTE

Najważniejsze rozróżnienie sprawdzane przez rekruterów:

  • Self join obsługuje ustaloną liczbę poziomów. Trzy kopie oznaczają trzy poziomy i nic więcej.
  • Rekursywne CTE obsługuje nieograniczoną głębokość, ponownie łącząc tabelę z samą sobą, aż przestaną pojawiać się nowe wiersze.

Zatem polecenie 'pokaż każdego pracownika i jego bezpośredniego menedżera' wymaga self join, ale polecenie 'wymień wszystkich przodków w całym łańcuchu' wymaga rekurencji.

Kategorie nadrzędne i podrzędne

Ten sam wzorzec służy do modelowania dowolnego drzewa: kategorii produktów, wątków komentarzy czy regionów geograficznych. Tabela categories z kolumną parent_id odwołującą się do własnej kolumny id ma identyczną strukturę jak przypadek pracownika i menedżera.

Rozpoznanie, że 'tabela z kluczem obcym odwołującym się do niej samej' oznacza 'self join lub rekurencję', to uniwersalna i przydatna umiejętność.

SELECT c.name AS category,
       p.name AS parent_category
FROM categories c
LEFT JOIN categories p ON c.parent_id = p.id;

Typowe błędy przy self join

Na rozmowach rekrutacyjnych należy zwrócić uwagę na następujące problemy:

  • Brak aliasów powodujący błędy dotyczące niejednoznacznych kolumn.
  • Użycie INNER JOIN i ciche pominięcie wierszy głównych, czyli wierszy z wartością NULL w kolumnie nadrzędnej.
  • Połączenie w niewłaściwym kierunku: e.id = m.manager_id zamiast e.manager_id = m.id.

Przed napisaniem warunku ON należy zawsze jasno określić, który alias oznacza element podrzędny, a który nadrzędny.

Kiedy używać self join

Po self join należy sięgać zawsze, gdy tabela wiąże wiersze z innymi wierszami tej samej tabeli:

  • Hierarchie z jednym ustalonym poziomem wyszukiwania, na przykład pracownik–menedżer.
  • Łączenie w pary lub porównywanie wierszy jednej tabeli, co zostanie omówione w następnej lekcji.

Jeśli relacja jest rekurencyjna i nie ma ograniczonej głębokości, należy wskazać rekursywne CTE jako lepsze narzędzie. To właśnie takie niuanse odróżniają osoby początkujące od programistów na średnim poziomie.

Szybki test

Sprawdźmy, czy dobrze rozumieją Państwo self join w hierarchiach.

Podsumowanie: SELF JOIN w hierarchiach

Najważniejsze informacje:

  • Self join to zwykłe złączenie, w którym ta sama tabela występuje po obu stronach, a poszczególne kopie rozróżnia się za pomocą aliasów.
  • Lista sąsiedztwa, czyli klucz obcy odwołujący się do tej samej tabeli, na przykład manager_id, pozwala modelować drzewo w jednej tabeli.
  • Należy używać INNER JOIN dla dopasowanych par, a LEFT JOIN, aby zachować wiersze główne z wartością NULL w kolumnach nadrzędnych.
  • Self join obsługuje ustaloną głębokość; przechodzenie na nieograniczoną głębokość wymaga rekursywnego CTE.

Często zadawane pytania

Czy lekcja „SELF JOIN dla hierarchii” jest bezpłatna?

Tak — pełny tekst „SELF JOIN dla hierarchii” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Coding Interview Prep, przejdź na CoddyKit PRO. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „SELF JOIN dla hierarchii”?

Łączenie tabeli z samą sobą w celu modelowania relacji pracownik–przełożony i rodzic–dziecko Ćwiczysz Coding Interview Prep z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Coding Interview Prep?

Nie wymagamy żadnego doświadczenia. Coding Interview Prep w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „SELF JOIN dla hierarchii”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Coding Interview Prep?

Tak. Każda lekcja Coding Interview Prep zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. CROSS JOIN i iloczyny kartezjańskie
  2. SELF JOIN dla hierarchii
  3. Porównywanie wierszy w jednej tabeli
  4. Wybór właściwego typu złączenia
← Powrót do Coding Interview Prep