Получить самый верхний элемент для любого элемента в цепочке (дереве) в Oracle Sql - PullRequest
0 голосов
/ 15 января 2020

Рассмотрим следующую структуру с некоторыми узлами:

        1
        /\
       2  3
       |  |
       4  5
       |  |
       6  7   
       |
       8

или

with mydata as (
 select 8 id ,6 id_before, 400 datum from dual union all
 select 6,4, 300 from dual union all
 select 4, 2, 200 from dual union all
 select 2,1, 10 from dual union all
 select 3, 1, 60 from dual union all
 select 5, 3, 800 from dual union all
 select 7, 5, 900 from dual 
)

Теперь, учитывая id узла, я хочу получить root node id

Например, для узла 7 root Примечание 1, для 5 root Узел 1 для 4 root Узел 1 et c.

Я пробовал что-то вроде этого:

select id, id_before,datum, SYS_CONNECT_BY_PATH(id_before,'/') as path,
SYS_CONNECT_BY_PATH(datum,'/') as datapath,
level,
CONNECT_BY_ROOT id_before
     from mydata
       where id=7
      connect by  id_before = prior id

с разочаровывающими результатами:

7   5   900 /1/3/5  /60/800/900 3   1
7   5   900 /3/5    /800/900    2   3
7   5   900 /5      /900        1   5

Есть идеи, как это исправить?

Спасибо.

1 Ответ

2 голосов
/ 15 января 2020

Вы можете использовать CONNECT_BY_ISLEAF в качестве фильтра для поиска элемента root:

Oracle Настройка :

CREATE TABLE mydata ( id, id_before, datum ) as
 select 8, 6, 400 from dual union all
 select 6, 4, 300 from dual union all
 select 4, 2, 200 from dual union all
 select 2, 1,  10 from dual union all
 select 3, 1,  60 from dual union all
 select 5, 3, 800 from dual union all
 select 7, 5, 900 from dual;

Запрос :

SELECT CONNECT_BY_ROOT( id ) AS id,
       id_before AS root_id,
       SYS_CONNECT_BY_PATH( id, ',' ) || ',' || id_before AS path
FROM   mydata
WHERE  CONNECT_BY_ISLEAF = 1
CONNECT BY id = PRIOR id_before;

Выход :

ID | ROOT_ID | PATH      
-: | ------: | :---------
 2 |       1 | ,2,1      
 3 |       1 | ,3,1      
 4 |       1 | ,4,2,1    
 5 |       1 | ,5,3,1    
 6 |       1 | ,6,4,2,1  
 7 |       1 | ,7,5,3,1  
 8 |       1 | ,8,6,4,2,1

db <> скрипка здесь

...