sql >> Databasteknik >  >> RDS >> Oracle

oracle hierarkisk fråga startklausul från join

Din r alias och rights tabellen den hänvisar till inte omfattas av den inline-vy du skapar. Du måste skapa hierarkin, vilket du fortfarande kan göra i en inline-vy, och sedan koppla den till rights tabell via dess folderid .

Du kan hämta hierarkin från:

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

Vilket är ungefär vad du gjorde, men det här hittar alla ättlingar från vilken startpunkt som helst och fångar även startpunkten som rootid . (Jag har lagt in path alltför bara för att visualisera hierarkin; du verkar inte vilja ha det i resultaten).

Du kan sedan ansluta det till din rättighetstabell, där varje användares folderid matchar någon rootid . Det kommer att lista dubbletter (t.ex. 685 kan komma till 5538 direkt eller via 5534), så du kan använda distinct för att eliminera dessa:

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;

Som med din data får 16 distinkta kombinationer:

    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

Du kan också använda rekursiv subquery factoring istället för en hierarkisk fråga:

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;

Ankarmedlemmen är en enkel sammanfogning mellan de två tabellerna för att få behörigheter på högsta nivån. Den rekursiva medlemmen letar sedan efter eventuella underordnade behörigheter för alla som redan hittats. Samma resultat, något annorlunda tillvägagångssätt.



  1. PDO ger inte undantag med obundna parametrar (och inga variabler i frågan)

  2. MySQL startar inte efter att ha ändrat my.cf

  3. Varför är laddning av SQLAlchemy-objekt via ORM 5-8x långsammare än rader via en rå MySQLdb-markör?

  4. Logstash:Det går inte att ansluta till extern Amazon RDS-databas