Votre r
alias et les rights
table à laquelle il se réfère ne sont pas dans la portée de la vue en ligne que vous créez. Vous devez générer la hiérarchie, ce que vous pouvez toujours faire dans une vue en ligne, puis la joindre aux rights
table via son folderid
.
Vous pouvez obtenir la hiérarchie à partir de :
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
...
C'est à peu près ce que vous faisiez, mais cela trouve tous les descendants à partir de n'importe quel point de départ et capture également le point de départ en tant que rootid
. (J'ai ajouté path
trop juste pour visualiser la hiérarchie; vous ne semblez pas vouloir cela dans les résultats).
Vous pouvez ensuite joindre cela à votre table de droits, où le folderid
de chaque utilisateur correspond à n'importe quel rootid
. Cela listera les doublons (par exemple, 685 peut accéder à 5538 directement ou via 5534), vous pouvez donc utiliser distinct
pour les éliminer :
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;
Qui, avec vos données, obtient 16 combinaisons distinctes :
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
Vous pouvez également utiliser la la factorisation récursive des sous-requêtes au lieu d'une requête hiérarchique :
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;
Le membre d'ancrage est une simple jointure entre les deux tables pour obtenir les autorisations de niveau supérieur. Le membre récursif recherche ensuite toutes les autorisations enfants de celles déjà trouvées. Même résultat, approche légèrement différente.