lesson 47 Advanced product analysis · advanced
Recursive CTEs
Repeat a query step to explore a hierarchy.
the idea
A recursive CTE has an anchor row and a recursive step joined by UNION ALL. The step uses the previous result until its stopping condition is false. Always include a termination condition.
tables in this lesson
The challenges use this data. Each column shows its type underneath; → marks a link to another table.
customers4 columns · 8 rows
| idinteger · key | nametext | citytext | joined_attext |
|---|---|---|---|
| 1 | Alice | Chicago | 2024-01-10 |
| 2 | Ben | Austin | 2024-02-12 |
| 3 | Cara | Seattle | 2024-03-05 |
| 4 | Dev | Chicago | 2024-04-20 |
| 5 | Elena | NULL | 2024-05-01 |
showing 5 of 8 rows
example
The idea in one query. Press Run to see what it returns; running examples never affects your progress.
WITH RECURSIVE numbers(n) AS ( SELECT 1 UNION ALL SELECT n+1 FROM numbers WHERE n<5 ) SELECT n FROM numbers;
Watch for: An unbounded recursive query is interrupted by the app time limit.
build it step by step
Each step changes one thing. Run them in order and watch the result change.
Start from a base row. A recursive CTE needs an anchor member. Here the sequence begins at 1 before the recursive step adds 1.
step-1.sqlSELECT 1 AS n;
Grow the sequence recursively. UNION ALL attaches rows produced from previous rows until the WHERE stop condition fails.
step-2.sqlWITH RECURSIVE numbers(n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM numbers WHERE n < 5 ) SELECT n FROM numbers;