What if you could create endless lists of numbers with just one simple query?
Why Recursive CTE for series generation in SQL? - Purpose & Use Cases
Imagine you need to create a list of numbers from 1 to 100 for a report, but you only have a basic table with a few rows. You try to write out each number manually or copy-paste them one by one.
Writing out each number by hand is slow and boring. Copy-pasting can cause mistakes like missing numbers or duplicates. If you want a longer list or a different range, you have to redo everything. It's easy to get tired and make errors.
Using a Recursive CTE lets you generate a series of numbers automatically inside your SQL query. It starts from a base number and keeps adding the next number until it reaches the limit you set. This saves time, avoids mistakes, and works for any range you want.
SELECT 1 AS number UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL ...
WITH RECURSIVE numbers AS (SELECT 1 AS number UNION ALL SELECT number + 1 FROM numbers WHERE number < 100) SELECT number FROM numbers;
You can quickly create any sequence of numbers or dates inside your database, making complex reports and calculations much easier.
A sales manager wants to see daily sales for the past month, even on days with no sales recorded. Using a recursive CTE to generate all dates in the month ensures every day appears in the report.
Manual number lists are slow and error-prone.
Recursive CTEs generate sequences automatically and flexibly.
This technique helps create complete reports and data sets easily.
Practice
Recursive CTE in SQL for series generation?Solution
Step 1: Understand Recursive CTE usage
Recursive CTEs are used to repeatedly execute a query to build results step-by-step.Step 2: Identify series generation purpose
They are commonly used to generate sequences like numbers or dates without needing extra tables.Final Answer:
To generate a sequence of numbers or dates step-by-step within a query -> Option AQuick Check:
Recursive CTE = sequence generation [OK]
- Confusing recursive CTE with JOIN operations
- Thinking recursive CTE deletes duplicates
- Assuming recursive CTE creates indexes
numbers generating numbers from 1?Solution
Step 1: Check correct WITH RECURSIVE syntax
The correct syntax starts withWITH RECURSIVE cte_name AS ( ... ).Step 2: Validate the recursive query structure
WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) correctly usesSELECT 1 AS numas anchor and recursive part withUNION ALLand stopping condition.Final Answer:
WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) -> Option BQuick Check:
Correct recursive CTE syntax = WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) [OK]
- Placing RECURSIVE after CTE name
- Missing parentheses around CTE query
- Omitting AS keyword
WITH RECURSIVE seq AS ( SELECT 1 AS n UNION ALL SELECT n + 2 FROM seq WHERE n < 7 ) SELECT * FROM seq;
What will be the output rows?
Solution
Step 1: Analyze anchor and recursive step
Anchor row is 1. Recursive step adds 2 each time: 1, 3, 5, 7.Step 2: Check stopping condition
Recursion stops when n < 7 is false. Since 7 is included, sequence ends at 7.Final Answer:
[1, 3, 5, 7] -> Option CQuick Check:
Start=1, step=+2, stop at 7 = [1,3,5,7] [OK]
- Assuming step is 1 instead of 2
- Stopping before reaching 7
- Including numbers beyond 7
WITH RECURSIVE count_up AS ( SELECT 1 AS num UNION ALL SELECT num + 1 FROM count_up ) SELECT * FROM count_up WHERE num <= 3;
Solution
Step 1: Check recursive part for stopping condition
The recursive SELECT lacks a WHERE clause to stop recursion, causing infinite loop.Step 2: Understand WHERE clause placement
The WHERE clause outside the CTE filters final results but does not stop recursion inside CTE.Final Answer:
Missing stopping condition inside the recursive part causing infinite recursion -> Option DQuick Check:
Stopping condition must be inside recursive CTE [OK]
- Placing stopping condition only in final SELECT
- Confusing UNION and UNION ALL effects
- Incorrect alias usage
Solution
Step 1: Understand date addition syntax
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT dt + INTERVAL '1 day' FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; usesdt + INTERVAL '1 day'which is standard SQL for adding one day to a date.Step 2: Check stopping condition and anchor
Anchor selects the start date as DATE type. Recursive part adds one day while date is less than '2024-01-05'.Step 3: Compare other options
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT DATE(dt, '+1 day') FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; uses SQLite styleDATE(dt, '+1 day'), which is not standard SQL. WITH RECURSIVE dates AS (SELECT '2024-01-01' AS dt UNION ALL SELECT dt + INTERVAL 1 DAY FROM dates WHERE dt <= '2024-01-05') SELECT * FROM dates; uses incorrect WHERE condition allowing extra date. WITH RECURSIVE dates AS (SELECT '2024-01-01' AS dt UNION ALL SELECT dt + 1 FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; adds integer to date incorrectly.Final Answer:
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT dt + INTERVAL '1 day' FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; -> Option AQuick Check:
Date + INTERVAL '1 day' is standard SQL date addition [OK]
- Using database-specific date functions in standard SQL
- Incorrect stopping condition allowing extra dates
- Adding integer directly to date without INTERVAL
Ready to prove it?
Pass the test and this pattern moves unknown
