Исходный код вики Рекурсивный запрос

Версия 4.3 от Alexandr Fokin на 2023/12/16 14:01

Скрыть последних авторов
Alexandr Fokin 3.1 1 Запрос задействует механизм [[CTE>>doc:Разработка.Базы данных.SQL.MSSQL.TSQL.CTE.WebHome]].
2
Alexandr Fokin 1.1 3 {{code language="sql"}}
Alexandr Fokin 2.8 4 WITH RECURSIVE tree (nm, id, level, pathstr)
5 AS
Alexandr Fokin 1.1 6 (
7 --Первый элемент в выборке. Начало рекурсии
Alexandr Fokin 2.8 8 SELECT
9 nm,
10 id,
11 0,
12 cast('' as text)
13 FROM tree_sample
14 WHERE id_parent is null
Alexandr Fokin 1.1 15
Alexandr Fokin 2.8 16 UNION ALL
Alexandr Fokin 1.1 17
18 --Каждый последующий элемент рекурсии
Alexandr Fokin 2.8 19 SELECT
20 tree_sample.nm,
21 tree_sample.id,
22 t.level + 1,
23 tree.pathstr + tree_sample.nm
24 FROM tree_sample
25 INNER JOIN tree
Alexandr Fokin 1.1 26 on tree.id = tree_sample.id_parent
27 )
28
Alexandr Fokin 2.8 29 SELECT
30 id,
31 space(level) + nm as nm
32 FROM tree
33 ORDER BY pathstr
Alexandr Fokin 1.1 34 {{/code}}
Alexandr Fokin 2.1 35
Alexandr Fokin 2.8 36 Рекурсивные SQL запросы
Alexandr Fokin 2.1 37 https://habr.com/ru/post/27439/
Alexandr Fokin 3.1 38
39 ----
40
41 **Дополнение:**
42
43 В некоторых случаях рекурсивного запроса можно избежать (в случае извлечения из хранилища некоторого агрегата).
44 Достаточно помимо ключа/отношения Parent-Child, добавить ключ/отношение Root-Child.
Alexandr Fokin 4.1 45 Таким образом можно извлечь все поддерево Root элемента за 1 join.
46 Это немного усложнит модель - в случае выполнения update нужно не забыть обновить оба поля. (Чтобы не допустить состояния, когда родительский элемент принадлежит к другому Root элементу)
Alexandr Fokin 3.1 47
48 ----
49
50