sql >> データベース >  >> RDS >> Oracle

Oracleの階層レベルとすべてのノード参照を取得します

    これは、再帰CTEを使用したソリューションです。 lvlを使用しました level以降の列ヘッダーとして Oracleの予約語です。用語には他の違いもあります。すぐ上のレベルには「親」を使用し、> =0ステップには「祖先」を使用します(ノードをそれ自体の祖先として表示するという要件に対応するため)。 ORDER BYを使用しました 出力を自分のものと一致させる句。順序付けられた行が必要な場合と不要な場合があります。

    あなたの質問は、再帰CTEの代わりに階層クエリを使用してこれを実行できるかどうかを確認するために、階層クエリについてもう一度詳しく読むように促しました。実際、CONNECT_BY_PATHを使用することで、できることはすでにわかっています。 、ただしsubstrを使用 その上で、階層パスのトップレベルを取得するだけでは、まったく満足のいくものではありません。より良い方法が必要です。 (それが階層クエリでそれを行う唯一の方法である場合、それが利用可能であれば、私は間違いなく再帰CTEルートに行きます)。適切なソリューションが見つかった場合は、ここに階層クエリソリューションを追加します。

    with h (      node, parent ) as (
           select 1   , null  from dual union all
           select 2   , 1     from dual union all
           select 3   , 2     from dual
         ),
         r (      node  , ancestor, steps ) as (
           select node  , node    , 0    
           from   h
           union all
           select r.node, h.parent, steps + 1
           from   h join r
                    on h.node = r.ancestor
         ) 
    select   node, ancestor, 
             1+ (max(steps) over (partition by node)) as lvl, steps
    from     r
    where    ancestor is not null
    order by lvl, steps desc;
    
    
          NODE   ANCESTOR        LVL      STEPS
    ---------- ---------- ---------- ----------
             1          1          1          0
             2          1          2          1
             2          2          2          0
             3          1          3          2
             3          2          3          1
             3          3          3          0
    

    追加 :階層クエリソリューション

    OK-見つけた。両方のソリューションをテストして、どちらが優れているかを確認してください。異なる設定でのテストから、再帰CTEは階層クエリよりもかなり高速でしたが、それは特定の状況に依存する可能性があります。また、再帰CTEはOracle11.2以降でのみ機能します。階層型ソリューションは古いバージョンで機能します。

    Anatoliyのものと一致するようにもう少しテストデータを追加しました。

    with h (      node, parent ) as (
           select 1   , null  from dual union all
           select 2   , 1     from dual union all
           select 3   , 2     from dual union all
           select 4   , 2     from dual union all
           select 5   , 4     from dual
         )
    select                                             node, 
               connect_by_root node                 as ancestor, 
               max(level) over (partition by node)  as lvl,
               level - 1                            as steps
    from       h
    connect by parent = prior node
    order by   node, ancestor;
    
    
    
          NODE   ANCESTOR        LVL      STEPS
    ---------- ---------- ---------- ----------
             1          1          1          0
             2          1          2          1
             2          2          2          0
             3          1          3          2
             3          2          3          1
             3          3          3          0
             4          1          3          2
             4          2          3          1
             4          4          3          0
             5          1          4          3
             5          2          4          2
             5          4          4          1
             5          5          4          0
    


    1. 別のデータベースのテーブルにあるMySQL外部キー?

    2. SQLクエリ:ある列から別の列とペアになっているアイテムを取得する方法。

    3. Doctrine2の行数

    4. 'Mysql:Classの未定義のメソッドinit'