Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Так получилось, что революции не произошло, но это совсем другая история
Рекурсия в БД — ЗЛО и не надо других вводить в заблуждение.
Но и подходить к СУБД с позиции тупой хранилки данных, пользуясь только синтаксисом самого первого стандарта SQL-89, согласитесь, тоже не правильно.
Ну, СУБД разные бывают. Те, интерфейс которых построен на языке SQL, как раз и надлежит рассматривать как чёрный ящик.
SELECT rownum as rn FROM dual CONNECT BY level <= (SELECT max(id) FROM test_table);
SELECT 1, level FROM dual CONNECT BY rownum <=10
select * from (select level from dual connect by level < 10) ;
(1) Россия
(2) Воронеж
(3) ООО "Рога и копыта"
(6) Главный офис
(7) Офис 1
(8) Офис 2
(9) Сервер 1
(5) Лиски
(10) ЛискиПресс
(4) Москва
set l="^Tree" //устанавливаем значение переменной
for { //цикл
set l=$query(@l) //берём следующий по очереди элемент дерева (алгоритм обхода функции $query сверху вниз затем справа налево)
quit:l="" //выходим из цикла когда всё обошли
set len=$querylength(l) //определяем глубину вложенности (вниз) текущего узла
for i=1:1:len {write " "} //печатаем отступы
write "(",$get(@l),") ",$querysubscript(l,len),! //печатем в скобках значение узла + его имя
}
s l="^Tree" f { s l=$q(@l) q:l="" s len=$ql(l) f i=1:1:len {w " "} w "(",$g(@l),")",$qs(l,len),! }
WITH RECURSIVE
Rec (id, pid, title)
AS (
SELECT id, pid, title FROM test_table
UNION ALL
SELECT test_table.id, test_table.pid, test_table.title
FROM Rec, test_table
WHERE Rec.id = test_table.pid
)
SELECT * FROM Rec
WHERE pid is null;
WITH
Rec (id, pid, title)
AS (
-- корневая часть
SELECT id, pid, title FROM test_table
WHERE pid is null
UNION ALL
-- рекурсивная часть
SELECT test_table.id, test_table.pid, test_table.title
FROM Rec, test_table
WHERE Rec.id = test_table.pid
)
SELECT * FROM Rec;
Иерархические (рекурсивные) запросы