2

Oracle11g の (id, parent_id) のような構造のテーブルがあります。

id    parent_id
---------------
1     (null)
2     (null)
3     1
4     3
5     3
6     2
7     2

これらの各IDに階層的にリンクされているすべての行を取得するためにクエリを実行したいので、結果は次のようになります。

root_id  id    parent_id
------------------------
1        3     1
1        4     3
1        5     3
2        6     2
2        7     2
3        4     3
3        5     3

私はかなり長い間connect byandstart withに苦労してきましたが、次のようなクエリで必要な結果の一部しか得られません。

select connect_by_root(id) root_id, id, parent_id from my-table
start with id=1
connect by prior id = parent_id

for完全な結果を得るためにループを使用したくありません。

何か案が ?

敬具、ジェローム・ルフレール

PS:最初の回答の後に編集し、必要な結果の一部を忘れていたことに気づきました...

4

3 に答える 3

3

あなたが投稿したクエリにはfrom句がなく、アンダースコアが残っていconnect_by_rootますが、実際にはそれらが問題の原因ではないと思います。

次のクエリは、探している結果を提供します。

select * from (
   select connect_by_root(id) root_id, id, parent_id
   from test1
   start with parent_id is null
   connect by prior id = parent_id)
where root_id <> id

中心的な問題は、ルート行を識別する方法を指定するのではなく、開始する特定の値を指定していたことです。に変更id = 1するparent_id is nullと、テーブルの内容全体を返すことができます。

また、結果セットからルート行をフィルタリングするための外部クエリを追加しました。これは、質問では言及されていませんが、目的の結果に表示されました。

SQLフィドルの例


コメント応答:

提供されているバージョンでは、の子孫を取得しますが、ルートとid = 3なるような方法では取得しません。3これは、絶対ルートから開始しているためです。start withこれを解決するのは簡単です。次の句を省略してください。

SELECT *
FROM
  (SELECT connect_by_root(id) root_id,
          id,
          parent_id
   FROM test1
CONNECT BY
   PRIOR id = parent_id)
WHERE root_id <> id

SQLフィドルの例

于 2012-05-22T15:01:47.130 に答える
2

これを試して:

select connect_by_root(id) root_id, id, parent_id
from your_table
start with parent_id is null
connect by prior id = parent_id
于 2012-05-22T15:00:48.320 に答える