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