Example 1
Walk an employee org chart from CEO down to individual contributors
The anchor selects Alice (the only row with no manager) at depth 0. Each recursive step finds employees whose manager_id matches a row already in org and increments the depth. Bob and Carol are both at depth 1. Dave reports to Bob and is at depth 2. The recursion terminates when no new employees are found.
CREATE TABLE employees (id INT, name VARCHAR(50), manager_id INT);
INSERT INTO
employees (id, name, manager_id)
VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Carol', 1),
(4, 'Dave', 2);WITH RECURSIVE
org AS (
SELECT
id,
name,
0 AS depth
FROM
employees
WHERE
manager_id IS NULL
UNION ALL
SELECT
e.id,
e.name,
o.depth + 1
FROM
employees e
JOIN org o ON e.manager_id = o.id
)
SELECT
name,
depth
FROM
org
ORDER BY
depth,
id;| name | depth |
|---|---|
| Alice | 0 |
| Bob | 1 |
| Carol | 1 |
| Dave | 2 |
CREATE TABLE employees (id INT, name VARCHAR(50), manager_id INT);
INSERT INTO
employees (id, name, manager_id)
VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Carol', 1),
(4, 'Dave', 2);WITH
org AS (
SELECT
id,
name,
0 AS depth
FROM
employees
WHERE
manager_id IS NULL
UNION ALL
SELECT
e.id,
e.name,
o.depth + 1
FROM
employees e
JOIN org o ON e.manager_id = o.id
)
SELECT
name,
depth
FROM
org
ORDER BY
depth,
id;| name | depth |
|---|---|
| Alice | 0 |
| Bob | 1 |
| Carol | 1 |
| Dave | 2 |
SQL Server omits the RECURSIVE keyword. All other engines use WITH RECURSIVE. The output is identical across all engines.