トップページに戻る
次の再帰with句のサンプルへ
前の再帰with句のサンプルへ
再帰with句05 階層問い合わせのconnect by nocycleを模倣
SQLパズル
noCycleT
ID nextID
-- ------
1 2
2 3
3 4
4 1
5 6
階層問い合わせを使った下記のクエリと同じ結果を取得する。
select ID,nextID,sys_connect_by_path(to_char(ID),',') as Path,
connect_by_IsCycle as IsCycle
from noCycleT
start with ID = 1
connect by nocycle prior nextID = ID;
出力結果
ID nextID Path IsCycle
-- ------ -------- -------
1 2 ,1 0
2 3 ,1,2 0
3 4 ,1,2,3 0
4 1 ,1,2,3,4 1
データ作成スクリプト
create table noCycleT(
ID number primary key,
nextID number);
insert into noCycleT values(1,2);
insert into noCycleT values(2,3);
insert into noCycleT values(3,4);
insert into noCycleT values(4,1);
insert into noCycleT values(5,6);
commit;
SQL
col path for a10
--■■■connect_by_IsCycleは模倣しない場合■■■
with rec(ID,nextID,path) as(
select ID,nextID,',' || to_char(ID)
from noCycleT
where ID=1
union all
select b.ID,b.nextID,a.path || ',' || to_char(b.ID)
from rec a,noCycleT b
where a.nextID = b.ID)
CYCLE ID SET IsLoop TO 'Y' DEFAULT 'N'
select ID,nextID,path
from rec
where IsLoop = 'N';
--■■■connect_by_IsCycleも模倣する場合■■■
with rec(TreeID,ID,nextID,path) as(
select ID,ID,nextID,',' || to_char(ID)
from noCycleT
where ID=1
union all
select a.TreeID,b.ID,b.nextID,a.path || ',' || to_char(b.ID)
from rec a,noCycleT b
where a.nextID = b.ID)
CYCLE ID SET IsLoop TO 'Y' DEFAULT 'N'
select TreeID,ID,nextID,path,
case when exists(select 1 from rec b
where b.IsLoop = 'Y'
and a.TreeID = b.TreeID
and a.nextID = b.ID)
then 1 else 0 end as IsCycle
from rec a
where IsLoop = 'N';
解説
同じ木で親子条件を満たして、かつ、訪問済なノードが存在すれば、
connect_by_IsCycleが1と判定してます。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
階層問い合わせのconnect by nocycleは、ループになる行を出力しませんが、
再帰with句のcycle句は、ループになる行を出力します。
with rec(ID,nextID,path) as(
select ID,nextID,',' || to_char(ID)
from noCycleT
where ID=1
union all
select b.ID,b.nextID,a.path || ',' || to_char(b.ID)
from rec a,noCycleT b
where a.nextID = b.ID)
CYCLE ID SET IsLoop TO 'Y' DEFAULT 'N'
select * from rec;
ID nextID path IsLoop
-- ------ ---------- ------
1 2 ,1 N
2 3 ,1,2 N
3 4 ,1,2,3 N
4 1 ,1,2,3,4 N
1 2 ,1,2,3,4,1 Y