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は直接または5534経由で5538に到達できます)、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;
    

    アンカーメンバーは、トップレベルの権限を取得するための2つのテーブル間の単純な結合です。次に、再帰メンバーは、既に見つかった子のアクセス許可を探します。同じ結果、わずかに異なるアプローチ。



    1. Linux上のasp.netコアアプリからテーブルを移行する方法

    2. SQL Server(T-SQL)で文字列の左側の部分を取得する

    3. カテゴリ別に重複せずにMySQL8の上位Nスコアを表示する

    4. EntityFramework6の動的MySQLデータベース接続