7

Oracle DB に次のテーブルがあるとします。

ID:    Name:     Parent_ID:
123    a         234
345    b         123
234    c         234
456    d         345
567    e         567
678    f         567

そして、私がやりたいことは、それぞれIDの(行として記述され、上に行くと、最終的にそれを取得する行にULTIMATE parent ID基づいて、再帰的に) を見つけることです。Parent_IDID = Parent_ID

したがって、たとえば、345 の親は 123 であり、123 の親は 234 であり、234 の親は 234 (つまり、チェーンのトップ) であり、したがって 345 の最終的な親は 234 です。

したがって、私の結果は次のようになります。

ID:    Name:     Ult_Parent_ID:    Ult_Parent_Name:
123    a         234               c
345    b         234               c
234    c         234               c
456    d         234               c
567    e         567               e
678    f         567               e

今日Oracleのステートメントについて知ったばかりConnect Byなので、これは私にとってまったく新しいことですが、クエリは次のように見える必要があると想像しています。

SELECT ID, Name, Parent_ID as Ult_Parent_ID, 
   (SELECT Name from MyTable t2 WHERE t2.ID = t1.Parent_ID) as Ult_Parent_Name
FROM MyTable t1
CONNECT BY PRIOR Parent_ID = ID;

今、私が言ったように、これはこの種の SQL での私の最初の刺し傷です - これは機能しません(次のエラーが発生[1]: ORA-01436: CONNECT BY loop in user dataし、SQL エディターでテーブル名が強調表示されます)。この種のクエリには句を使用しSTART WITHますが、そのロジックは正しいようです。

助けてください/正しい方向に私を向けるのを手伝ってください!!!

ありがとう!!!

4

4 に答える 4

1

これをお試し下さい:

SELECT ID, Name, Parent_ID as Ult_Parent_ID, 
   (SELECT Name from MyTable t2 WHERE t2.ID = t1.Parent_ID) as Ult_Parent_Name, 
   LEVEL
FROM MyTable t1
CONNECT BY NOCYCLE Parent_ID = PRIOR ID
START WITH Parent_ID = ID;

NOCYCLEルーツがどのように定義されているかという理由で、使用する必要があると思います。

LEVEL説明のために疑似列を追加しました。最終クエリに含める必要はありません。

テスト データを使用したSQL フィドル

于 2013-10-16T17:03:53.930 に答える
1

CONNECT BY は直接の親を提供しますが、最終的な親を取得するには、再帰サブクエリを使用します。(CONNECT_BY_ROOTエマニュエルによって説明されているようにも機能します)

WITH r (id, parent, ultimate_parent, name, ultimate_parent_name, lvl) as
   (SELECT id, parent_id AS parent, parent_id AS ultimate_parent, name, name as ultimate_parent_name, 0 lvl
    FROM mytable
       WHERE parent_id = id -- identifies a root
UNION ALL
    SELECT m.id, r.id, ultimate_parent, m.name, r.ultimate_parent_name, r.lvl + 1
    FROM r join mytable m on m.parent_id = r.id  -- joins child with parent
    WHERE m.parent_id <> m.id -- to avoid cycles
   )
SELECT * FROM r ;

サブクエリの最初の部分はルートを取得し、2 番目の部分は子を接続します。Parentは直接の親でultimate_parent、 は最終的な親です。

于 2013-10-16T17:08:33.670 に答える
0

テーブル test_data を作成します (order_number number(10), line_id number(10), parent_line_id number (10));

              insert into test_data values (1000, 101, 100);

              insert into test_data values (1000, 100, '');

              insert into test_data values (3000, 301, 300);

              insert into test_data values (3000, 300, '');


              select * from test_data

              select * from test_data 
              where order_number in (1000,3000) 
              start with parent_line_id is null 
              connect by prior line_id= parent_line_id
于 2014-03-28T06:12:13.060 に答える