Skip to main content

Recursive CTE Patterns

Recursive CTEs are ideal for org charts, category trees, and dependency chains.

Recursion Components​

PartPurpose
Anchor queryStarting rows
Recursive queryExpands from previous level
Stop conditionPrevents infinite recursion

Hierarchy Example​

WITH RECURSIVE org_tree AS (
SELECT employee_id, manager_id, full_name, 0 AS depth
FROM employees
WHERE manager_id IS NULL

UNION ALL

SELECT e.employee_id, e.manager_id, e.full_name, ot.depth + 1
FROM employees e
JOIN org_tree ot ON e.manager_id = ot.employee_id
WHERE ot.depth < 10
)
SELECT employee_id, manager_id, full_name, depth
FROM org_tree
ORDER BY depth, employee_id;
employee_idmanager_idfull_namedepth
1NULLCEO0
51VP Engineering1
125Engineering Manager2

Common Pitfalls​

PitfallConsequencePrevention
Missing recursion depth guardRunaway recursionAdd depth limits or cycle protection logic
Using non-indexed join keysSlow expansion on large treesIndex parent-child key columns
No clear ordering in outputHard-to-read hierarchyInclude depth and ordering columns

Quick Reference​

WITH RECURSIVE t AS (
SELECT ...
UNION ALL
SELECT ... FROM source JOIN t ON ...
)
SELECT * FROM t;

What's Next​