Вашият r
псевдоним и rights
таблицата, към която се отнася, не са в обхвата на вградения изглед, който създавате. Трябва да генерирате йерархията, което все още можете да направите във вграден изглед, и след това да я присъедините към rights
таблица чрез нейния folderid
.
Можете да получите йерархията от:
select connect_by_root(folderid) as rootid, folderid,
sys_connect_by_path(folderid, '/') as path
from folders
connect by parentfolderid = prior folderid
order by rootid, path;
ROOTID FOLDERID PATH
---------- ---------- ------------------------------
5162 5162 /5162
5162 28568 /5162/28568
5162 6343 /5162/6343
5534 5534 /5534
5534 41578 /5534/41578
5534 113867 /5534/41578/113867
5534 127030 /5534/41578/127030
5534 5162 /5534/5162
5534 28568 /5534/5162/28568
5534 6343 /5534/5162/6343
5534 5538 /5534/5538
5538 5538 /5538
...
Което до голяма степен е това, което правите, но това намира всички наследници от всяка начална точка и също така улавя началната точка като rootid
. (Добавих path
твърде просто за визуализиране на йерархията; изглежда не искате това в резултатите).
След това можете да го присъедините към вашата таблица с права, където folderid
на всеки потребител съответства на всеки rootid
. Това ще изведе дубликати (напр. 685 може да стигне до 5538 директно или чрез 5534), така че можете да използвате distinct
за да елиминирате тези:
select distinct r.userid, f.folderid
from rights r
join (
select connect_by_root(folderid) as rootid, folderid
from folders
connect by prior folderid = parentfolderid
) f
on f.rootid = r.folderid
order by r.userid, f.folderid;
Което с вашите данни получава 16 различни комбинации:
USERID FOLDERID
---------- ----------
685 5162
685 5534
685 5538
685 6343
685 28568
685 41578
685 113867
685 127030
686 5162
686 6343
686 28568
686 41578
686 113867
686 127030
725 113867
725 127030
Можете също така да използвате факториране на рекурсивни подзаявки вместо йерархична заявка:
with rcte (userid, folderid) as (
select r.userid, f.folderid
from rights r
join folders f on f.folderid = r.folderid
union all
select rcte.userid, f.folderid
from rcte
join folders f on f.parentfolderid = rcte.folderid
)
select distinct userid, folderid
from rcte
order by userid, folderid;
Членът на котвата е просто съединение между двете таблици за получаване на разрешения от най-високо ниво. След това рекурсивният член търси всички дъщерни разрешения за всички вече намерени. Същият резултат, малко по-различен подход.