SQL / CHAPTER 11

Recursive CTEs and termination

Advanced

Build iterative query results with an explicit stopping rule.

By the end of this chapter

  • Separate anchor and recursive terms
  • Trace accumulated rows
  • Prevent unbounded traversal

The idea

A recursive common table expression starts with an anchor query and repeatedly applies a recursive term to produce additional rows. A simple sequence can begin at one and emit the next integer while its bound allows progress. Trace the rows contributed by the anchor separately from the rows produced later, because an off-by-one stopping condition can add or omit a boundary value.

Recursive graph traversal also needs a cycle policy. A hierarchy may be acyclic by contract, but arbitrary graph data can revisit the same nodes indefinitely. UNION can suppress duplicate complete rows in suitable formulations, while UNION ALL preserves them. Adding changing columns such as depth can make repeated nodes distinct complete rows, so deduplication alone is not a universal cycle detector. State a visited-node strategy or a justified bound.

SQL example
WITH RECURSIVE n(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM n WHERE x<4)
SELECT x FROM n ORDER BY x;
Result
x
1
2
3
4

The anchor contributes one; values below four generate their successor, and four generates no further row.

Try it yourself

Trace a sequence ending at six, then explain how a graph cycle changes the termination problem.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

Open SQL coding challenges

CHECK YOUR UNDERSTANDING

Chapter checkpoint

How many rows does an anchor SELECT 1 followed by x+1 WHERE x<3 produce?