Oracle
 sql >> база данни >  >> RDS >> Oracle

Oracle йерархична клауза за стартиране на заявка от присъединяване

Вашият r псевдоним и rights таблицата, към която се отнася, не са в обхвата на вградения изглед, който създавате. Трябва да генерирате йерархията, което все още можете да направите във вграден изглед, и след това да я присъедините към rights таблица чрез нейния folderid .

Можете да получите йерархията от:

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

Което до голяма степен е това, което правите, но това намира всички наследници от всяка начална точка и също така улавя началната точка като rootid . (Добавих path твърде просто за визуализиране на йерархията; изглежда не искате това в резултатите).

След това можете да го присъедините към вашата таблица с права, където folderid на всеки потребител съответства на всеки rootid . Това ще изведе дубликати (напр. 685 може да стигне до 5538 директно или чрез 5534), така че можете да използвате distinct за да елиминирате тези:

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;

Което с вашите данни получава 16 различни комбинации:

    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

Можете също така да използвате факториране на рекурсивни подзаявки вместо йерархична заявка:

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;

Членът на котвата е просто съединение между двете таблици за получаване на разрешения от най-високо ниво. След това рекурсивният член търси всички дъщерни разрешения за всички вече намерени. Същият резултат, малко по-различен подход.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка при изключване на PDB ORA-17528

  2. update x set y =null отнема много време

  3. Oracle:зареждане на голям xml файл?

  4. Променливата на таблицата се попълва само с една стойност

  5. SQL „И“ или „ИЛИ“ е на първо място?