はじめに
Oracleの階層問い合わせについて、基本事項から使用例まで、SQLのイメージを交えて解説します。本稿では、Level
擬似列、sys_connect_by_path
関数、order siblings by
を扱います。
対象読者
- Oracleの階層問い合わせを使いたい方
- OracleのSQLの理解を深めたい方
必要な環境
本稿で扱うSQLは、Oracle 10.2.0.1.0で動作確認しました。
1. Level擬似列
Level
擬似列は、ノードのレベルを表します。start with
句の条件を満たしたノードのレベルが1となり、子供はレベル2、孫はレベル3といった感じでレベルが増えていきます。サンプルを見てみましょう。
ID | nextID |
1 | 2 |
2 | 3 |
3 | 4 |
3 | 5 |
4 | 6 |
5 | 7 |
7 | 8 |
8 | 9 |
IDが1の行から、親のnextID = 子のID
であることを親子条件として、階層問い合わせを行います。
select ID,nextID,Level, sys_connect_by_path(to_char(ID),',') as Path from LinkT start with ID = 1 connect by prior nextID = ID;
ID | nextID | Level | Path |
1 | 2 | 1 | ,1 |
2 | 3 | 2 | ,1,2 |
3 | 4 | 3 | ,1,2,3 |
4 | 6 | 4 | ,1,2,3,4 |
3 | 5 | 3 | ,1,2,3 |
5 | 7 | 4 | ,1,2,3,5 |
7 | 8 | 5 | ,1,2,3,5,7 |
8 | 9 | 6 | ,1,2,3,5,7,8 |
Level擬似列のイメージは、下記となります。
もうひとつサンプルを見てみましょう。レベルの上限を3として、階層問い合わせを行った後、where
句でレベルが1または3の行を抽出してます。
select ID,nextID,Level, sys_connect_by_path(to_char(ID),',') as Path from LinkT where Level in(1,3) start with ID = 1 connect by prior nextID = ID and Level <=3;
ID | nextID | Level | Path |
1 | 2 | 1 | ,1 |
3 | 4 | 3 | ,1,2,3 |
3 | 5 | 3 | ,1,2,3 |
2. sys_connect_by_path関数
sys_connect_by_path
関数は、根からの経路を表します。前問のサンプルを再度見てみましょう。
select ID,nextID,Level, sys_connect_by_path(to_char(ID),',') as Path from LinkT start with ID = 1 connect by prior nextID = ID;
ID | nextID | Level | Path |
1 | 2 | 1 | ,1 |
2 | 3 | 2 | ,1,2 |
3 | 4 | 3 | ,1,2,3 |
4 | 6 | 4 | ,1,2,3,4 |
3 | 5 | 3 | ,1,2,3 |
5 | 7 | 4 | ,1,2,3,5 |
7 | 8 | 5 | ,1,2,3,5,7 |
8 | 9 | 6 | ,1,2,3,5,7,8 |
sys_connect_by_path
関数のイメージは、下記となります。
connect by
句では、sys_connect_by_path
関数を使うことはできません。
select ID,nextID from LinkT start with ID = 1 connect by prior nextID = ID and instr(sys_connect_by_path(to_char(ID),','),'7') = 0;
where
句でも、sys_connect_by_path
関数を使うことはできません。
select ID,nextID from LinkT where instr(sys_connect_by_path(to_char(ID),','),'7') = 0 start with ID = 1 connect by prior nextID = ID;