有向グラフ、無向グラフへの階層問い合わせ
山岸賢治 [著] 2009/11/10 14:00

SourceCode 0.96 KB
1 2 →

はじめに

 Oracleの階層問い合わせについて、基本事項から使用例まで、SQLのイメージを交えて解説します。本稿では、connect by nocycleconnect_by_IsCycle疑似列を扱います。

対象読者

  • Oracleの階層問い合わせを使いたい方
  • OracleのSQLの理解を深めたい方

 connect by nocycleを使用する階層問い合わせは、有向グラフや無向グラフなどのグラフ構造の知識を必要としますので、『グラフ理論 - Wikipedia』などを読まれてからの方が理解しやすいと思います。

必要な環境

 本稿で扱うSQLは、Oracle 10.2.0.1.0で動作確認しました。

1. connect by nocycle

 cycleという英単語は名詞で、意味は「ひと巡り、一巡、周期」です。connect by nocycleを使うと、経路上で訪問済であるノードへの再訪問を防いだ階層問い合わせを行うことができます。

 connect by nocycleはデータ構造が有向グラフや無向グラフである場合によく使われます。サンプルを見てみましょう。

RosenMap
IDNextID
13
35
5null
2023
2325
2520

 (親の行の)NextID = (子の行の)IDを親子条件とし、ID=1の行を木の根として、到達可能なIDを列挙してみます。

ID=1の行を木の根として、到達可能なIDを列挙
select ID,NextID,Level,
sys_connect_by_path(to_char(ID),'-') as path
  from RosenMap
start with ID = 1
connect by prior NextID = ID;
出力結果
IDNextIDLevelpath
131-1
352-1-3
5null3-1-3-5

 次は、ID=20の行を木の根として、到達可能なIDを列挙してみます。

ORA-01436: ユーザー・データでCONNECT BYのループが発生しました。
select ID,NextID,Level,
sys_connect_by_path(to_char(ID),'-') as path
  from RosenMap
start with ID = 20
connect by prior NextID = ID;
ERROR:
ORA-01436: ユーザー・データでCONNECT BYのループが発生しました。

 start with ID = 20によって、ID=20の行から階層問い合わせが開始されますが、ID=20の行の子供がID=23の行。ID=23の行の子供がID=25の行。ID=25の行の子供がID=20の行。といったデータになっていて、経路上で訪問済であるノードへの再訪問が行われるため、ORA-01436が発生してしまいます。ちなみに、sys_connect_by_path関数で経路を表示してます。

 このようなデータの時には、connect by nocycleを使うと、親子関係があるけど経路上で訪問済であるノードへの再訪問を防いだ階層問い合わせを行うことができます。

ID=20の行を木の根として、到達可能なIDを列挙
select ID,NextID,Level,
sys_connect_by_path(to_char(ID),'-') as path
  from RosenMap
start with ID = 20
connect by nocycle prior NextID = ID;
出力結果
IDNextIDLevelpath
20231-20
23252-20-23
25203-20-23-25

 connect_by_IsCycle疑似列のサンプルも紹介しておきます。connect_by_IsCycle疑似列は、経路上で訪問済であるノードを子供に持てば1、そうでなければ0となります。下記がサンプルです。

connect_by_IsCycle疑似列のサンプル
select ID,NextID,Level,
sys_connect_by_path(to_char(ID),'-') as path,
connect_by_IsCycle as IsCycle
  from RosenMap
start with ID = 20
connect by nocycle prior NextID = ID;
出力結果
IDNextIDLevelpathIsCycle
20231-200
23252-20-230
25203-20-23-251

 connect by nocycleconnect_by_IsCycle疑似列のイメージは、下記となります。赤色のバツ印で親子関係があるけど経路上で訪問済であるノードへの再訪問を防いでます。

connect by nocycleとconnect_by_IsCycle疑似列のイメージ
connect by nocycleとconnect_by_IsCycle疑似列のイメージ

1 2
→
INDEX
Oracleの階層問い合わせ(4) (connect by nocycle)
Page1
はじめに
対象読者
必要な環境
1. connect by nocycle
2. connect_by_IsCycle疑似列
最後に
参考資料
プロフィール
山岸賢治 ヤマギシケンジ

Oracle ACEの1人。
OracleSQLパズルの運営者。
ORACLE MASTER Silver Oracle Database 10g
(研修受講で)ORACLE MASTER Gold Oracle Database 10g
ソフトウェア開発技術者 (情報処理技術者試験)
第二種情報処理技術者 (情報処理技術者試験)
 


注目の求人情報
システムエンジニア/ゾーランジャパン株式会社
DSPアセンブリ言語およびC/C++言語による画像処理用ファームウェア・ソフトウェア開発、組み込み用OSを...
ビジネス戦略・事業運営/日系ITコンサルティングファーム
クライアントの課題解決の為の各種ソリューション提供
サーバ技術者・NE/株式会社 テクノクリエイティブ
高品質なネットワーク・サーバ・ミドルウェアなど最新のハードウェア、 ソフトウェア技術を駆使し、お...

(最新日付順)
名前(ゲストの方もコメントをどうぞ):*
アイコン:
なし

内容(テキストのみ1200文字まで):*

投稿規定に同意して

スポンサーサイト

この記事のトラックバックURL: