Din r
alias og rights
tabel, den henviser til, er ikke omfattet af den inline-visning, du opretter. Du skal generere hierarkiet, hvilket du stadig kan gøre i en indlejret visning, og derefter forbinde det med rights
tabel via dens folderid
.
Du kan få hierarkiet fra:
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
...
Hvilket stort set var det, du lavede, men dette finder alle efterkommere fra ethvert udgangspunkt og fanger også udgangspunktet som rootid
. (Jeg har indsat path
for bare at visualisere hierarkiet; du ser ikke ud til at ønske det i resultaterne).
Du kan derefter tilføje det til din rettighedstabel, hvor hver brugers folderid
matcher enhver rootid
. Det vil vise dubletter (f.eks. kan 685 komme til 5538 direkte eller via 5534), så du kan bruge distinct
for at fjerne disse:
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;
Som med dine data får 16 forskellige kombinationer:
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
Du kan også bruge rekursiv subquery factoring i stedet for en hierarkisk forespørgsel:
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;
Ankermedlemmet er en simpel sammenføjning mellem de to tabeller for at få tilladelser på øverste niveau. Det rekursive medlem søger derefter efter eventuelle underordnede tilladelser for dem, der allerede er fundet. Samme resultat, lidt anderledes tilgang.