Skip to content

Commit 306a063

Browse files
committed
Update Patterns Recursive CTEs.md
1 parent 65abacb commit 306a063

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

Patterns Recursive CTEs.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ parent: Design Patterns
66
permalink: /patterns/rec-cte
77
---
88

9-
Because, by design, SQL delegates the flow control of statement evaluation to the database engine, the standard SQL grammar does not include any flow control structures. The only exception is expression-level branching control. This control structure has operator and function representation, which is why it naturally integrates within an expression. Adding statement-level flow controls, such as branching or loops, necessitates grammar extension or special conventions. Recursive CTEs (RCTEs) follow the latter approach and implement the while/repeat loop structure. A general loop structure has four essential components: initialization code, the body of the loop, syntactic elements marking the beginning and end of the body code, and a means to exit the loop (termination conditions).
10-
11-
RCTEs do not introduce any special grammar/syntax; instead, it uses the standard SELECT statement syntax and a special convention. The result is quite contrived; for this reason, comprehending and mastering RCTEs may not be straightforward. Because the sole function of SQL is the construction and manipulation of row sets (views), the initialization and loop body blocks of an RCTE constitute complete SELECT statements. The initialization query generates starting view used as one of the sources by the body query. Each execution cycle of the loop body yields a new view used as one of the sources by the following loop cycle. There are two possible termination conditions. If the loop body includes the LIMIT clause, the loop terminates after the specified number of rows is processed. Alternatively, the loop terminates after processing all previously returned rows, with the loop body returning empty row sets.
9+
By design, SQL delegates statement-level flow control to the database engine, so the standard SQL grammar does not include any flow control structures. The only exception is expression-level branching control. This control structure has operator and function representations, so it naturally integrates within an expression (similar to other functions/operators). Adding statement-level flow controls, such as branching or loops, necessitates grammar extension or special conventions. Recursive CTEs (RCTEs) follow the latter approach and implement the while/repeat loop structure without special grammar/syntax. The result is quite contrived; thus, comprehending and mastering RCTEs may not be straightforward.
1210

13-
By convention, initialization and loop body SELECT blocks should be part of the same CTE. Because a CTE is, in turn, a SELECT statement, a set operator (such as UNION) must glue the initialization and loop body blocks, yielding a compound SELECT. Naturally, the initialization block goes first, followed by the body. The body query, by convention, uses its CTE name as one of the sources in the FROM clause. The CTE may include multiple set operations, and the first SELECT block referencing its CTE's name constitutes marks the beginning of the body block, with all preceding code forming the initialization query.
11+
A general loop structure has two essential code blocks - initialization and loop body. Conventionally, the RCTE analogous blocks must fit within a single WITH clause member block. Because the latter only supports SELECT-type members, an RCTE must also represent a valid SELECT statement. At the same time, RCTEs, like SQL in general, focus on row sets/views manipulation. The idea is that the initialization query generates a starting view used as one of the sources by the first loop cycle. Each execution of the loop body yields a new view used as one of the sources by the following loop cycle. Accordingly, both code blocks must represent complete SELECT statements. And because the two SELECT blocks must form a valid SELECT query, they should be glued together via a set operator, such as UNION.
1412

15-
The resulting view of an RCTE query is the compound consisting of the row set produced by the initialization query combined with all row sets returned by individual loop cycles using the specified set operator (the operator separating the initialization and the body blocks).
13+
By convention, the resulting view of an RCTE query is the compound consisting of the row set produced by the initialization query combined with all row sets returned by individual loop cycles using the specified set operator (the operator separating the initialization and the body blocks). This convention permits, for example, retrieving a subtree from a hierarchy modeled with the parent reference pattern.
1614

17-
Yet another convention is related to the meaning of the RCTE name. Outside the RCTE, its name refers to the resulting view above. This meaning is the same for both ordinary and recursive CTEs. An ordinary CTE cannot use its name as one of its sources. Within an RCTE, on the other hand, its name refers to the processing frame/view, which, to a first approximation, contains the row set returned by the previous cycle or the initialization query for the first cycle. More precisely, the processing frame is a single row view (in a sense, a pointer to the next exiting row of the processing queue) sitting at the tip of a dynamically generated processing queue, as discussed later.
15+
Yet another convention is related to the meaning of the RCTE name. Outside the RCTE, its name refers to the resulting view above. This meaning is the same for both ordinary and recursive CTEs. An ordinary CTE cannot use its name as one of its sources. An RCTE, on the other hand, must use its name. Within an RCTE, its name refers to the processing frame/view, which, to a first approximation, contains the row set returned by the previous cycle or the initialization query for the first cycle. In other words, the inner and outer references to the RCTE name mean two completely different things.
16+
17+
Another essential feature of a loop structure is loop body start/end markers. By convention, the RCTE loop body starts with the first SELECT query portion that uses the RCTE name as one of its sources. The loop body must incorporate all code through the end of the RCTE code block, with all preceding code forming the initialization query. The body part may be a compound SELECT query combined using the same set operator as the one that combines the body and the initialization code.
18+
19+
There are two possible termination conditions. If the loop body includes the LIMIT clause, the loop terminates after the specified number of rows is processed. Alternatively, the loop terminates after processing all previously returned rows, with the loop body returning empty row sets.
20+
21+
<!--
22+
More precisely, the processing frame is a single row view (in a sense, a pointer to the next exiting row of the processing queue) sitting at the tip of a dynamically generated processing queue, as discussed later.
1823
1924
[Recursive CTEs][] is
25+
-->
2026

2127
~~~sql
2228
WITH RECURSIVE

0 commit comments

Comments
 (0)