Разберем пример, когда в нерекурсивной части несколько строк. Построим наборы чисел от 100 до 103 и от 200 до 201:
WITH RECURSIVE lv_initial AS (
SELECT 100 AS start_number,
4 AS count_iterations
UNION ALL
SELECT 200 AS start_number,
2 AS count_iterations
),
lv_numbers (start_number, count_iterations, current_iteration, result_number) AS (
SELECT start_number,
count_iterations,
1 AS current_iteration,
start_number AS result_number
FROM lv_initial
UNION ALL
SELECT p.start_number,
p.count_iterations,
p.current_iteration + 1,
p.result_number + 1
FROM lv_numbers p
WHERE p.current_iteration < p.count_iterations
)
SELECT n.start_number,
n.result_number
FROM lv_numbers n
ORDER BY n.start_number,
n.result_number
| # | start_number | result_number |
|---|---|---|
| 1 | 100 | 100 |
| 2 | 100 | 101 |
| 3 | 100 | 102 |
| 4 | 100 | 103 |
| 5 | 200 | 200 |
| 6 | 200 | 201 |
Обрати внимание, ключевое слово RECURSIVE стоит не перед рекурсивным подзапросом, а сразу после WITH.
Как выполняется запрос
Шаг 1. Выполняется нерекурсивная часть подзапроса.
Таблица lv_initial:
| # | start_number | count_iterations |
|---|---|---|
| 1 | 100 | 4 |
| 2 | 200 | 2 |
Результат нерекурсивной части:
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
Временная таблица:
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
Шаг 2. Рекурсивная часть выполняется 1-й раз
Начальная временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
Результат подзапроса
SELECT p.start_number,
p.count_iterations,
p.current_iteration + 1,
p.result_number + 1
FROM lv_numbers p
WHERE p.current_iteration < p.count_iterations
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 2 | 101 |
| 2 | 200 | 2 | 2 | 201 |
Общий результат запроса
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
| 3 | 100 | 4 | 2 | 101 |
| 4 | 200 | 2 | 2 | 201 |
Временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 2 | 101 |
| 2 | 200 | 2 | 2 | 201 |
Шаг 3. Рекурсивная часть выполняется 2-й раз
Начальная временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 2 | 101 |
| 2 | 200 | 2 | 2 | 201 |
Результат подзапроса
SELECT p.start_number,
p.count_iterations,
p.current_iteration + 1,
p.result_number + 1
FROM lv_numbers p
WHERE p.current_iteration < p.count_iterations
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 3 | 102 |
Общий результат запроса
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
| 3 | 100 | 4 | 2 | 101 |
| 4 | 200 | 2 | 2 | 201 |
| 5 | 100 | 4 | 3 | 102 |
Временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 3 | 102 |
Шаг 4. Рекурсивная часть выполняется 3-й раз
Начальная временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 3 | 102 |
Результат подзапроса
SELECT p.start_number,
p.count_iterations,
p.current_iteration + 1,
p.result_number + 1
FROM lv_numbers p
WHERE p.current_iteration < p.count_iterations
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 4 | 103 |
Общий результат запроса
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
| 3 | 100 | 4 | 2 | 101 |
| 4 | 200 | 2 | 2 | 201 |
| 5 | 100 | 4 | 3 | 102 |
| 6 | 100 | 4 | 4 | 103 |
Временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 4 | 103 |
Шаг 5. Рекурсивная часть выполняется 4-й раз
Начальная временная таблица
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 4 | 103 |
Результат подзапроса
SELECT p.start_number,
p.count_iterations,
p.current_iteration + 1,
p.result_number + 1
FROM lv_numbers p
WHERE p.current_iteration < p.count_iterations
0 строк
Общий результат запроса
| # | start_number | count_iterations | current_iteration | result_number |
|---|---|---|---|---|
| 1 | 100 | 4 | 1 | 100 |
| 2 | 200 | 2 | 1 | 200 |
| 3 | 100 | 4 | 2 | 101 |
| 4 | 200 | 2 | 2 | 201 |
| 5 | 100 | 4 | 3 | 102 |
| 6 | 100 | 4 | 4 | 103 |
Временная таблица пуста. На этом рекурсивная часть запроса завершает выполнение.
Шаг 6. Выполняется основной запрос
SELECT n.start_number,
n.result_number
FROM lv_numbers n
ORDER BY n.start_number,
n.result_number
| # | start_number | result_number |
|---|---|---|
| 1 | 100 | 100 |
| 2 | 100 | 101 |
| 3 | 100 | 102 |
| 4 | 100 | 103 |
| 5 | 200 | 200 |
| 6 | 200 | 201 |