Question presented to candidate:
"We store employees in one table with a manager_id column. Given a manager, write a query that returns everyone who reports to them, directly or through other managers, with how many levels down each person is."
What a strong answer should cover:
- Why a plain self join is not enough: each join adds exactly one level, and the depth of the tree is unknown
- A recursive CTE: anchor = the direct reports (
manager_id = :id), recursive member joinsemployees.manager_id = reports.id, carrying alevelcolumn - Deciding whether the manager themself is in the result (anchor on
id = :idwith level 0, or onmanager_id = :idwith level 1) - Presentation: a
pathcolumn to print the chart in tree order, and aggregating the walk for headcount per manager - Performance: an index on
manager_idturns each iteration into index lookups (PostgreSQL shows a Nested Loop with an Index Scan per working-table row) - Robustness: a depth guard or cycle check when the data could contain a loop; alternatives for very read-heavy trees (closure table, materialized path)
Clarifying questions expected:
- Should the result include the manager, and do you want the depth or the full chain for each person?
- Can the data contain cycles or people with several managers (a graph, not a tree)?
- How big is the org and how often is this run: per request, or for a report?
Code / implementation expected: Yes — a recursive CTE listing all reports with their level, plus ideally the tree-ordered view or the headcount roll-up.
Schema used by the examples: