Ihr r
Alias und die rights
Tabelle, auf die es sich bezieht, sind nicht im Geltungsbereich der von Ihnen erstellten Inline-Ansicht. Sie müssen die Hierarchie generieren, was Sie immer noch in einer Inline-Ansicht tun können, und diese dann mit den rights
verbinden Tabelle über ihre folderid
.
Sie können die Hierarchie abrufen von:
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
...
Das ist ziemlich genau das, was Sie getan haben, aber das findet alle Nachkommen von jedem Startpunkt und erfasst auch den Startpunkt als rootid
. (Ich habe path
eingefügt auch nur um die Hierarchie zu visualisieren; Sie scheinen das in den Ergebnissen nicht zu wollen).
Sie können das dann mit Ihrer Rechtetabelle verbinden, in der die folderid
jedes Benutzers enthalten ist stimmt mit jeder rootid
überein . Dadurch werden Duplikate aufgelistet (z. B. kann 685 direkt oder über 5534 zu 5538 gelangen), sodass Sie distinct
verwenden können um diese zu beseitigen:
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;
Was mit Ihren Daten 16 verschiedene Kombinationen ergibt:
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
Sie könnten auch rekursive Unterabfragefaktorisierung verwenden statt einer hierarchischen Abfrage:
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;
Das Ankerelement ist ein einfacher Join zwischen den beiden Tabellen, um die Berechtigungen der obersten Ebene zu erhalten. Das rekursive Mitglied sucht dann nach allen untergeordneten Berechtigungen von bereits gefundenen. Gleiches Ergebnis, etwas anderer Ansatz.