Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Иерархический запрос  [new]
dimyaz
Member

Откуда:
Сообщений: 442
Всем доброго!

Есть выборка следующего содержания:

with t1 as (
    select 'app5' name , 'app4' producer from dual union all
    select 'app4' name , 'app3' producer from dual union all
    select 'app3' name , 'app2' producer from dual union all
    select 'app2' name , 'app1' producer from dual union all
    select 'app5' name , 'app3' producer from dual union all
    select 'app5' name , 'app2' producer from dual union all
    select 'app6' name , 'app1' producer from dual union all
    select 'app6' name , 'app2' producer from dual union all
    select 'app5' name , 'app1' producer from dual
)
select t1.*
from t1


Результат этой выборки показывает зависимости между объектами, где Name это объект, а Producer это родитель.
Нужно вычислить корневые объекты, и вывести все максимальные ветки этих зависимостей от корневых объектов
Так вот, пытаюсь вытащить список всех веток через level и через sys_connect_by_path, но получается полная фигня. Данные сильно размножаются и выходит много лишних веток, так как не могу исключить малые ветки, которые уже входят в другие(Например app1/app5 есть в ветке app1/app2/app3/app4/app5).

По результату ожидается такой вывод:

Ветка Level Name
1 1 app1
1 2 app2
1 3 app3
1 4 app4
1 5 app5
2 1 app1
2 2 app2
2 3 app6


Либо такой
Ветка Path
1 app1/app2/app3/app4/app5
2 app1/app2/app6


Хотя, если получится первый вариант, второй будет построить 5сек.
11 ноя 19, 11:23    [22013354]     Ответить | Цитировать Сообщить модератору
 Re: Иерархический запрос  [new]
-2-
Member

Откуда:
Сообщений: 15330
dimyaz
от корневых объектов
начинай с листовых.
11 ноя 19, 11:27    [22013358]     Ответить | Цитировать Сообщить модератору
 Re: Иерархический запрос  [new]
Anton_Demin
Member

Откуда: Ставрополь
Сообщений: 294
dimyaz,

https://habr.com/ru/post/43955/
https://urvanov.ru/2017/05/28/иерархические-запросы-в-oracle/
https://roquebase.wordpress.com/2017/07/17/иерархические-запросы-в-oracle/
11 ноя 19, 11:38    [22013370]     Ответить | Цитировать Сообщить модератору
 Re: Иерархический запрос  [new]
MazoHist
Member

Откуда:
Сообщений: 145
dimyaz,
with t1 as (
    select 'app5' name , 'app4' producer from dual union all
    select 'app4' name , 'app3' producer from dual union all
    select 'app3' name , 'app2' producer from dual union all
    select 'app2' name , 'app1' producer from dual union all
    select 'app5' name , 'app3' producer from dual union all
    select 'app5' name , 'app2' producer from dual union all
    select 'app6' name , 'app1' producer from dual union all
    select 'app6' name , 'app2' producer from dual union all
    select 'app5' name , 'app1' producer from dual
)
, t2 as (select producer from t1 minus select name from t1)
select max(connect_by_root producer||sys_connect_by_path(name,'/')) keep (dense_rank first order by level desc) path
from t1
where connect_by_isleaf =1
connect by prior name = producer 
start with t1.producer in (select producer from t2)
--group by  case when connect_by_isleaf =1 then name end 
group by name --поскольку where connect_by_isleaf =1


Сообщение было отредактировано: 11 ноя 19, 11:50
11 ноя 19, 11:43    [22013377]     Ответить | Цитировать Сообщить модератору
 Re: Иерархический запрос  [new]
MazoHist
Member

Откуда:
Сообщений: 145
Учитываем multipath-инг
with t1 as (
    select 'app9' name , 'app4' producer from dual union all
    select 'app5' name , 'app4' producer from dual union all
    select 'app4' name , 'app3' producer from dual union all
    select 'app5' name , 'app8' producer from dual union all
    select 'app8' name , 'app3' producer from dual union all
    select 'app3' name , 'app2' producer from dual union all
    select 'app2' name , 'app1' producer from dual union all
    select 'app3' name , 'app7' producer from dual union all
    select 'app7' name , 'app1' producer from dual union all
    select 'app5' name , 'app3' producer from dual union all
    select 'app5' name , 'app2' producer from dual union all
    select 'app6' name , 'app1' producer from dual union all
    select 'app6' name , 'app2' producer from dual union all
    select 'app5' name , 'app1' producer from dual
)
, t2 as (select producer from t1 minus select name from t1)
, t3 as (select connect_by_root producer||sys_connect_by_path(name,'/') path
              , level as lvl
              , max(level) over (partition by name )  as maxlvl
           from t1
          where connect_by_isleaf =1
        connect by prior name = producer 
          start with t1.producer in (select producer from t2))
select * from t3 where lvl = maxlvl
11 ноя 19, 15:53    [22013669]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить