0Pricing
SQL Interview Prep · Lekcja

Elementy zakotwiczający i rekurencyjny

Dwuczęściowa struktura rekurencyjnego CTE oraz sposób działania warunku zakończenia

Elementy zakotwiczający i rekurencyjny to bezpłatna lekcja SQL Interview Prep na CoddyKit. To lekcja 1 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 SQL Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Dlaczego pojawiają się rekurencyjne CTE

Gdy osoba prowadząca rozmowę pokaże Państwu schemat organizacyjny, zestawienie materiałowe lub drzewo kategorii i poprosi o wyświetlenie wszystkich potomków, sprawdza, czy sięgną Państwo po rekurencyjne CTE. Zwykłe złączenia mogą przechodzić tylko przez ustaloną liczbę poziomów, natomiast rekurencja obsługuje dowolną głębokość.

Charakterystyczne sformułowania w pytaniu to „na dowolną głębokość” lub „aż do samego dołu”. To jest właściwy sygnał. W tej lekcji poznają Państwo dwuetapową strukturę wspólną dla każdego rekurencyjnego CTE: człon kotwiczący i człon rekurencyjny.

Dwuczęściowy szkielet

Rekurencyjne CTE zawsze zawiera słowo kluczowe WITH RECURSIVE (Postgres, SQLite, MySQL 8+; SQL Server pomija RECURSIVE) oraz treść złożoną z dwóch zapytań połączonych przez UNION ALL:

  • Człon kotwiczący — wiersze początkowe, wykonywany raz.
  • Człon rekurencyjny — odwołuje się do nazwy CTE i jest wykonywany wielokrotnie.

Proszę zapamiętać ten szkielet; osoby prowadzące rozmowy kwalifikacyjne często proszą o napisanie go od zera.

WITH RECURSIVE cte AS (
    -- anchor member
    SELECT ...
    UNION ALL
    -- recursive member
    SELECT ... FROM cte JOIN ...
)
SELECT * FROM cte;

Rola członu kotwiczącego

Człon kotwiczący jest zwykłym zapytaniem, które nie odwołuje się do CTE. Tworzy wiersze zalążkowe — punkt startowy na poziomie zerowym. W przypadku schematu organizacyjnego jest to zwykle dyrektor generalny (wiersz, którego menedżer ma wartość NULL), a w przypadku szeregu liczb jest to pierwsza liczba.

Człon kotwiczący jest wykonywany dokładnie raz. Jego wynik staje się pierwszą partią wierszy przekazywaną do kroku rekurencyjnego.

-- Anchor: the top of the hierarchy
SELECT id, name, manager_id, 1 AS depth
FROM employees
WHERE manager_id IS NULL

Rola członu rekurencyjnego

Człon rekurencyjny odwołuje się do CTE po nazwie. W każdej iteracji łączy wiersze utworzone w poprzedniej iteracji z tabelą bazową, aby znaleźć kolejny poziom.

Nie widzi całego dotychczasowego CTE — widzi tylko wiersze dodane w bezpośrednio poprzednim kroku. To najważniejszy model mentalny, którego znajomość sprawdzają osoby prowadzące rozmowy.

-- Recursive: children of the rows found so far
SELECT e.id, e.name, e.manager_id, c.depth + 1
FROM employees e
JOIN cte c ON e.manager_id = c.id

Połączenie elementów

Połącz człon kotwiczący i rekurencyjny za pomocą UNION ALL, a silnik będzie automatycznie wykonywać kolejne iteracje. Każde przejście dopisuje następny poziom, aż człon rekurencyjny zwróci zero wierszy; wtedy rekurencja się zatrzymuje.

Poniżej znajduje się kompletny, gotowy do uruchomienia przykład przechodzenia po schemacie organizacyjnym, który śledzi również depth.

WITH RECURSIVE org AS (
    SELECT id, name, manager_id, 1 AS depth
    FROM employees
    WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id, o.depth + 1
    FROM employees e
    JOIN org o ON e.manager_id = o.id
)
SELECT id, name, depth FROM org ORDER BY depth, id;

Jak działa zatrzymywanie rekurencji

Rekurencja zatrzymuje się, gdy człon rekurencyjny nie utworzy żadnych nowych wierszy. Nie trzeba jawnie stosować licznika pętli — złączenie naturalnie wyczerpuje się po dotarciu do liści drzewa.

W przykładzie schematu organizacyjnego, gdy dotrzemy do pracowników bez bezpośrednich podwładnych, złączenie w następnej iteracji nie znajdzie dzieci, zwróci pusty wynik, a silnik zakończy działanie. Zrozumienie tego samoczynnego kończenia jest klasycznym pytaniem dodatkowym.

UNION ALL a UNION

Osoby prowadzące rozmowy często pytają, dlaczego używamy UNION ALL, a nie UNION. Są dwa powody:

  • Wydajność — UNION usuwa duplikaty w każdej iteracji, co jest kosztowne.
  • Poprawność — w drzewie zduplikowane wiersze zwykle nie mogą wystąpić, więc usuwanie duplikatów byłoby niepotrzebną pracą.

Po UNION należy sięgać tylko wtedy, gdy struktura jest grafem i świadomie chcą Państwo scalać powtarzające się węzły — jednak dla bezpieczeństwa cykli lepsze są jawne zabezpieczenia (omówione później).

Śledzenie głębokości i ścieżki

Dwie dodatkowe kolumny znacznie zwiększają użyteczność wyników rekurencyjnych i są często wymagane podczas rozmów kwalifikacyjnych:

  • depth — rozpocząć od wartości 1 w członie kotwiczącym i zwiększać o 1 w członie rekurencyjnym.
  • path — gromadzić łańcuch identyfikatorów lub nazw, aby można było zobaczyć drogę od korzenia do węzła.

Budowanie path jako ciągu znaków służy również później do wykrywania cykli.

WITH RECURSIVE org AS (
    SELECT id, name, manager_id, 1 AS depth,
           CAST(name AS VARCHAR(1000)) AS path
    FROM employees WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id, o.depth + 1,
           o.path || ' > ' || e.name
    FROM employees e JOIN org o ON e.manager_id = o.id
)
SELECT name, depth, path FROM org;

Typy kolumn muszą się zgadzać

Subtelna pułapka: człon kotwiczący i człon rekurencyjny muszą zwracać taką samą liczbę kolumn o zgodnych typach. Jeśli tworzony jest ciąg znaków path, początkową wartość w członie kotwiczącym należy rzutować na typ o wystarczająco dużym rozmiarze, np. VARCHAR(1000), w przeciwnym razie silnik może obciąć wartość albo zgłosić błąd niezgodności typów w kolejnych iteracjach.

To dokładnie taki szczegół, który osoba prowadząca rozmowę może celowo wykorzystać, aby sprawdzić, czy rzeczywiście uruchamiali Państwo rekurencyjne CTE, a nie tylko czytali o nim.

Przykład zestawienia materiałowego

Ten sam szkielet rozwiązuje problem zestawienia materiałowego: mając daną część, należy wyświetlić każdą część składową na dowolnej głębokości. Człon kotwiczący wybiera główny zespół, a człon rekurencyjny przechodzi po powiązaniach od parent_part do child_part.

Proszę zauważyć, że struktura jest identyczna jak w przypadku schematu organizacyjnego — zmieniają się tylko nazwy kolumn. Rozpoznanie, że jeden szkielet pasuje do wielu problemów, jest właściwą umiejętnością przydatną podczas rozmowy.

WITH RECURSIVE bom AS (
    SELECT child_part, parent_part, 1 AS lvl
    FROM parts WHERE parent_part = 'ENGINE'
    UNION ALL
    SELECT p.child_part, p.parent_part, b.lvl + 1
    FROM parts p JOIN bom b ON p.parent_part = b.child_part
)
SELECT child_part, lvl FROM bom;

Uwagi dotyczące dialektów

Szybka ściąga dotycząca różnych dialektów, którą doceniają osoby prowadzące rozmowy:

  • PostgreSQL, SQLite, MySQL 8+: WITH RECURSIVE name AS (...).
  • SQL Server: wystarczy WITH name AS (...) — słowo kluczowe RECURSIVE jest domyślne, a silnik wymusza domyślną wartość MAXRECURSION równą 100.
  • Oracle: obsługuje zarówno rekurencyjne CTE, jak i starszą składnię CONNECT BY.

Powiedzenie „SQL Server nie używa słowa RECURSIVE” pokazuje rzeczywistą znajomość różnych rozwiązań.

Szybkie sprawdzenie

Proszę sprawdzić, czy rozumieją Państwo dwuetapową strukturę.

Podsumowanie

Opanowali Państwo szkielet rekurencyjnego CTE:

  • WITH RECURSIVE + człon kotwiczący + UNION ALL + człon rekurencyjny.
  • Człon kotwiczący inicjuje poziom zerowy i jest wykonywany raz.
  • Człon rekurencyjny łączy wynik poprzedniej iteracji z tabelą bazową i działa, dopóki nie zwróci żadnych wierszy.
  • Należy używać UNION ALL, śledzić depth i path oraz zapewnić zgodność typów kolumn.

Następnie: zastosowanie tego szkieletu do przechodzenia po rzeczywistym schemacie organizacyjnym w dół i w górę.

Często zadawane pytania

Czy lekcja „Elementy zakotwiczający i rekurencyjny” jest bezpłatna?

Tak — pełny tekst „Elementy zakotwiczający i rekurencyjny” 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 SQL Interview Prep, przejdź na CoddyKit PRO. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „Elementy zakotwiczający i rekurencyjny”?

Dwuczęściowa struktura rekurencyjnego CTE oraz sposób działania warunku zakończenia Ćwiczysz SQL 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ąć SQL Interview Prep?

Nie wymagamy żadnego doświadczenia. SQL 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 1 z 4.

Ile czasu zajmuje lekcja „Elementy zakotwiczający i rekurencyjny”?

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 SQL Interview Prep?

Tak. Każda lekcja SQL 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. Elementy zakotwiczający i rekurencyjny
  2. Przechodzenie po strukturze organizacyjnej
  3. Generowanie szeregów liczb i dat
  4. Unikanie nieskończonej rekurencji
← Powrót do SQL Interview Prep