Oracle
 sql >> Base de données >  >> RDS >> Oracle

clause de début de requête hiérarchique oracle à partir de la jointure

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.