CTEs - Common Table Expressions
CTEs (Common Table Expressions)
CTEs only exist within the context of a single SQL statement. They are typically used in more complex queries to improve readability, structure, and modularity. A CTE is introduced with the WITH keyword and behaves like a temporary, named result set that can be referenced by the main query.
The difference between CTEs and subqueries is primarily in how they are processed: CTEs allow naming and reusing a result set, improve clarity, and (depending on the SQL engine) may be optimized or materialized differently. They also uniquely support recursion.
Syntax
The WITH clause binds the output of the inner query to a temporary table with the given name.
Example: Create a CTE called cteName that contains a single value:
WITH cteName AS (
SELECT 1
)
SELECT * FROM cteName;Column names may be bound explicitly:
WITH cteName (col1, col2) AS (
SELECT 1, 2
)
SELECT col1 + col2
FROM cteName;A single query may contain multiple CTE declarations:
Recursive CTEs
Adding the RECURSIVE keyword after WITH allows a CTE to reference itself. This enables recursion in SQL, such as generating sequences or traversing hierarchical data.
The Anatomy of a Recursive CTE
A Recursive CTE always has three specific parts. If you miss one, it won't work.
The Anchor Member (The Starter): This runs once at the very beginning. It creates the initial row(s).
The Recursive Member (The Loop): This references the CTE itself. It takes the output of the previous step and uses it to generate new rows.
The Terminator (The Stop Sign): This is usually a
WHEREclause inside the recursive member. Without this, your query runs forever (infinite loop).
Visualizing the Execution
Let's look at your example of counting 1 to 10.
Step 1: The Anchor Runs
SQL runs
SELECT 1.Result so far:
[1]Note: This row is now effectively "passed" to the recursive part.
Step 2: Recursion Round 1
SQL looks at the previous result (
1).It runs
SELECT counter + 1(which is1 + 1).It checks the terminator: Is
1 < 10? Yes.Result so far:
[1, 2]
Step 3: Recursion Round 2
SQL looks at the new result from the last step (
2).It runs
SELECT counter + 1(which is2 + 1).It checks the terminator: Is
2 < 10? Yes.Result so far:
[1, 2, 3]
... Steps 4 through 9 happen ...
Step 10: The Stop
SQL looks at the previous result (
10).It runs
SELECT counter + 1(which is11).It checks the terminator: Is
10 < 10? NO.The recursive part returns nothing.
The loop breaks.
Final Result:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Last updated