Oracle
 sql >> Database >  >> RDS >> Oracle

clausola di avvio della query gerarchica Oracle da join

Il tuo r alias e i rights la tabella a cui fa riferimento non rientrano nell'ambito della vista in linea che stai creando. Devi generare la gerarchia, cosa che puoi ancora fare in una vista in linea, e poi unirla ai rights tabella tramite il suo folderid .

Puoi ottenere la gerarchia da:

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                         
...

Che è più o meno quello che stavi facendo, ma questo trova tutti i discendenti da qualsiasi punto di partenza e cattura anche il punto di partenza come rootid . (Ho inserito path troppo solo per visualizzare la gerarchia; non sembra che tu lo voglia nei risultati).

Puoi quindi unirlo alla tua tabella dei diritti, dove il folderid di ogni utente corrisponde a qualsiasi rootid . Questo elencherà i duplicati (ad es. 685 può arrivare a 5538 direttamente o tramite 5534), quindi puoi usare distinct per eliminare quelli:

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;

Che con i tuoi dati ottiene 16 combinazioni distinte:

    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

Puoi anche utilizzare fattorizzazione ricorsiva di sottoquery invece di una query gerarchica:

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;

Il membro anchor è un semplice join tra le due tabelle per ottenere le autorizzazioni di primo livello. Il membro ricorsivo cerca quindi tutte le autorizzazioni figlio di quelle già trovate. Stesso risultato, approccio leggermente diverso.