11gR2以上であれば、connect by
階層構文の代わりにrecursive subquery factoringを使用できます。
あなたのテーブルを持つt
呼び出された場合:あなたが行うことができます
CHILD_ID PARENT_ID CHILD_T
---------- ---------- -------
0 root
1 0 first
2 1 second
3 2 third
4 2 fourth
5 6 fifth
6 3 sixth
7 6 seventh
:
with r (child_id, child_title, id_path, title_path) as (
select child_id, child_title, to_clob(null), to_clob(null)
from t
where parent_id is null
union all
select t.child_id, t.child_title,
t.parent_id ||','|| r.id_path, r.child_title ||'|'|| r.title_path
from r
join t on t.parent_id = r.child_id
)
select child_id, id_path, title_path
from r
order by child_id;
CHILD_ID ID_PATH TITLE_PATH
---------- -------------------- ----------------------------------------
0
1 0, root|
2 1,0, first|root|
3 2,1,0, second|first|root|
4 2,1,0, second|first|root|
5 6,3,2,1,0, sixth|third|second|first|root|
6 3,2,1,0, third|second|first|root|
7 6,3,2,1,0, sixth|third|second|first|root|
アンカー部材は、CLOBのにパスを回します。再帰メンバは各タイトルをCLOBに追加し、CLOBをそのデータ型として保持します。
、彼らが表示されることはありませんので、あなたは少し末尾のコンマ/バーを切り落とす、またはクエリを変更することができます。
with r (parent_id, child_id, child_title, id_path, title_path) as (
select parent_id, child_id, child_title, to_clob(null), to_clob(null)
from t
where parent_id is null
union all
select t.parent_id, t.child_id, t.child_title,
t.parent_id || case when r.parent_id is not null then ',' end || r.id_path,
r.child_title || case when r.parent_id is not null then '|' end || r.title_path
from r
join t on t.parent_id = r.child_id
)
select child_id, id_path, title_path
from r
order by child_id;
CHILD_ID ID_PATH TITLE_PATH
---------- -------------------- ----------------------------------------
0
1 0 root
2 1,0 first|root
3 2,1,0 second|first|root
4 2,1,0 second|first|root
5 6,3,2,1,0 sixth|third|second|first|root
6 3,2,1,0 third|second|first|root
7 6,3,2,1,0 sixth|third|second|first|root
をあなたのサンプル値はCLOBの必要性を実証し、より多くのデータに追加することはありませんダミーのテーブルに生成された値が4Kを超えることを示しています。
insert into t
select level + 7, level + 6, 'title'
from dual
connect by level <= 2000;
with r (...) -- as above
select max(length(id_path)), max(length(title_path))
from r;
MAX(LENGTH(ID_PATH)) MAX(LENGTH(TITLE_PATH))
-------------------- -----------------------
8920 12031
だけで明確にします。あなたの問題は予期された結果ではなく、むしろ4kの制限がありますか? –
はい、私の問題は4kの制限です。私は先に接続してパスを取得することができます。しかし、結果は4k限界を超えると予想されます。 – ujwal
メインテーブルが頻繁に変更されることが予想されるため、私は気にしないclobに設定された結果に一時テーブルを作成するバックアップ方法があります。中間ノードがある場合はすべての子ノードを注意する必要があります。除去された。 – ujwal