sql >> Base de Datos >  >> RDS >> Oracle

Cláusula de inicio de consulta jerárquica de Oracle desde la unión

Tu r alias y los rights la tabla a la que se refiere no están dentro del alcance de la vista en línea que está creando. Debe generar la jerarquía, que aún puede hacer en una vista en línea, y luego unirla a los rights tabla a través de su folderid .

Puede obtener la jerarquía 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                         
...

Que es más o menos lo que estabas haciendo, pero esto encuentra todos los descendientes desde cualquier punto de inicio y también captura el punto de inicio como rootid . (He incluido path demasiado justo para visualizar la jerarquía; parece que no quieres eso en los resultados).

Luego puede unir eso a su tabla de derechos, donde el folderid de cada usuario coincide con cualquier rootid . Eso mostrará una lista de duplicados (por ejemplo, 685 puede llegar a 5538 directamente o a través de 5534), por lo que puede usar distinct para eliminarlos:

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;

Que con sus datos obtiene 16 combinaciones distintas:

    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

También puede usar factorización de subconsultas recursivas en lugar de una consulta jerárquica:

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;

El miembro ancla es una unión simple entre las dos tablas para obtener los permisos de nivel superior. A continuación, el miembro recursivo busca los permisos secundarios de los que ya se han encontrado. Mismo resultado, enfoque ligeramente diferente.