Learn SQL/Advanced/Interview Patterns/SQL Recursive Hierarchy

SQL Recursive Hierarchy

The same WITH RECURSIVE pattern from the CTEs series — this is where it shows up as a named interview question.

What & Why

"Walk the org chart," "find all descendants of a category," "get a comment's full reply thread" — these are all the identical recursive CTE pattern from the CTEs lesson series, just described in interview language.

See How It Works

BUSINESS QUESTION

Product wants a feature-to-feedback hierarchy built from product.feedback.feature_id.

idnamedescriptionteamreleased_atdeprecated_at
1Activation ChecklistGuides new users through setupgrowth2024-01-20NULL
2CSV ExportExports report dataplatform2024-02-14NULL
3Invite NudgesPrompts workspace collaborationgrowth2024-03-05NULL
4Legacy DashboardOriginal reporting surfaceanalytics2023-08-102024-06-01
iduser_idfeature_idratingnps_scorecommentcreated_at
1101159Clear and useful2024-01-25 12:15:00+00
210224NULLExport worked well2024-02-20 15:40:00+00
3103147Helpful setup flow2024-03-18 09:05:00+00
410433NULLNeeds clearer timing2024-04-08 17:30:00+00
EXAMPLE QUERY
WITH RECURSIVE nodes AS (
  SELECT
    'feature:' || f.id AS node_id,
    NULL::text AS parent_id,
    f.name AS node_name,
    'feature'::text AS node_type
  FROM product.features f
  UNION ALL
  SELECT
    'feedback:' || fb.id,
    'feature:' || fb.feature_id,
    'rating ' || fb.rating,
    'feedback'::text
  FROM product.feedback fb
  WHERE fb.feature_id IS NOT NULL
),
hierarchy AS (
  SELECT node_id, parent_id, node_name, node_type, 0 AS depth
  FROM nodes
  WHERE parent_id IS NULL
  UNION ALL
  SELECT child.node_id, child.parent_id, child.node_name, child.node_type, parent.depth + 1
  FROM nodes child
  JOIN hierarchy parent ON child.parent_id = parent.node_id
)
SELECT node_id, parent_id, node_name, node_type, depth
FROM hierarchy
ORDER BY SPLIT_PART(COALESCE(parent_id, node_id), ':', 2)::int, depth, node_id;
RESULT — features and their feedback children
node_idparent_idnode_namenode_typedepth
feature:1NULLActivation Checklistfeature0
feedback:1feature:1rating 5feedback1
feedback:3feature:1rating 4feedback1
feature:2NULLCSV Exportfeature0
feedback:2feature:2rating 4feedback1
feature:3NULLInvite Nudgesfeature0
feedback:4feature:3rating 3feedback1
feature:4NULLLegacy Dashboardfeature0

The recursive hierarchy starts with feature roots and attaches each feedback row at depth 1.

Advanced business practice

Sign up free to try it on a real business scenario