WITH RECURSIVE has a base case and a step that refers to itself, repeating until the step returns nothing. It is how you query a parent/child hierarchy of unknown depth.
WITH RECURSIVE tree AS (
SELECT id, name, manager_id, 1 AS depth
FROM employee WHERE id = 1 -- base
UNION ALL
SELECT e.id, e.name, e.manager_id, t.depth + 1
FROM employee e JOIN tree t ON e.manager_id = t.id -- step
WHERE t.depth < 10 -- guard
)
SELECT * FROM tree ORDER BY depth;
id | name | manager_id | depth
1 | Ann | NULL | 1
4 | Bob | 1 | 2
9 | Carl | 4 | 3
-- The depth guard is not optional in production: a cycle in the data makes
-- the recursion run until the server runs out of memory. UNION instead of
-- UNION ALL also stops cycles, at the cost of deduplicating every step.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-25