Разберем пример, когда в нерекурсивной части несколько строк. Построим наборы чисел от 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 |