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 NULLRola 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.idPołą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ść —
UNIONusuwa 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 kluczoweRECURSIVEjest domyślne, a silnik wymusza domyślną wartośćMAXRECURSIONró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ćdepthipathoraz 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
- Elementy zakotwiczający i rekurencyjny
- Przechodzenie po strukturze organizacyjnej
- Generowanie szeregów liczb i dat
- Unikanie nieskończonej rekurencji