Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Startklausel für hierarchische Oracle-Abfrage von Join

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.