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.