Иерархический список из рекурсивного sql-запроса

#sql #oracle #recursion #sql-order-by

#sql #Oracle #рекурсия #sql-порядок по

Вопрос:

итак, у меня есть таблица sql tab с информацией об отце (c_id_1) и дочернем (c_id_2)

       C_ID     C_ID_1     C_ID_2
---------- ---------- ----------
         1          1          4
         2          1          5
         3          1          6
[...]
 

это означает, что 1 является отцом 4 , 5 и 6
Я использую рекурсивный запрос, подобный описанному здесь https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL

 WITH R ( C_ID, C_ID_1 , C_ID_2, HIE) AS
(
    SELECT C_ID, C_ID_1 , C_ID_2, 1 as HIE FROM tab WHERE C_ID_1=1
    UNION ALL
    SELECT A.C_ID , A.C_ID_1, A.C_ID_2, B.HIE 1 FROM tab A
    INNER JOIN R B ON A.C_ID_1 = B.C_ID_2 
)   
SELECT * FROM R;
 

При этом создается список, включающий всю информацию об отце-ребенке, начиная 1 со столбца HIE , указывающего уровень записи

       C_ID     C_ID_1     C_ID_2        HIE
---------- ---------- ---------- ----------
         1          1          4          1
[...]
         4          1          2          1
         5          1          7          1
[...]
         6          2          3          2
         7          2          8          2
         8          2          9          2
         9          3         10          3
[...]
 

Как бы мне изменить порядок этого результата, чтобы получить иерархический список, в котором все дочерние элементы будут находиться под их отцом, выглядящим следующим образом:

       C_ID     C_ID_1     C_ID_2        HIE
---------- ---------- ---------- ----------
         1          1          4          1
[...]
         4          1          2          1
         6          2          3          2
         9          3         10          3
         7          2          8          2
         8          2          9          2
         5          1          7          1
[...]
 

Таким образом, верхний элемент любой заданной строки либо C_ID_1[i]==C_ID_1[i-1] или C_ID_1[i]==C_ID_2[i-1]

Ответ №1:

Сначала вам нужно использовать это предложение ДЛЯ ПОИСКА ГЛУБИНЫ ПО C_ID_2, ЗАДАННОМУ порядку1, и с порядком по порядку1, как показано ниже. Более подробную информацию смотрите на этой странице https://oracle-base.com/articles/11g/recursive-subquery-factoring-11gr2

 WITH R ( C_ID, C_ID_1 , C_ID_2, HIE) AS
(
    SELECT C_ID, C_ID_1 , C_ID_2, 1 as HIE FROM tab WHERE C_ID_1=1
    UNION ALL
    SELECT A.C_ID , A.C_ID_1, A.C_ID_2, B.HIE 1 FROM tab A
    INNER JOIN R B ON A.C_ID_1 = B.C_ID_2 
)
SEARCH DEPTH FIRST BY C_ID_2 SET order1   
SELECT * FROM R
ORDER BY order1
;