木構造を持つテーブルの深さを求めるSQL
例えばこの図のような木構造を持つテーブルがあるとする。
この木はレコードとして、一意のIDと親となるIDを表すPARENT_IDをセットで持つ。
テーブルとしてはこのようになる。
ID | PARENT_ID |
---|---|
0 | (null) |
1 | 0 |
2 | 1 |
3 | 1 |
4 | 1 |
5 | 4 |
6 | 4 |
7 | 4 |
8 | 7 |
9 | 7 |
10 | 8 |
11 | 8 |
12 | 4 |
このとき、この木における各IDの深さは下記のようなSQLで求めることができる。
SELECT ID, PARENT_ID, LEVEL
FROM IDTABLE
START WITH PARENT_ID IS NULL
CONNECT BY PRIOR ID = PARENT_ID;
出力結果はこうなる
ID | PARENT_ID | LEVEL |
---|---|---|
0 | (null) | 1 |
1 | 0 | 2 |
2 | 1 | 3 |
3 | 1 | 3 |
4 | 1 | 3 |
5 | 4 | 4 |
6 | 4 | 4 |
7 | 4 | 4 |
8 | 7 | 5 |
9 | 7 | 6 |
10 | 8 | 6 |
11 | 8 | 6 |
12 | 4 | 4 |
どんなときに使うのか
自分が使った例としてはArcSDEの更新履歴ツリーの深さ管理がある。
ArcSDEはユーザが接続したバージョン(更新履歴のタグ)に対して木の根からの更新履歴をたどるようにして画面にそのバージョンの状態を描画する。
このとき更新履歴ツリーが深いと読み込みの回数が増え、描画や追加の更新が遅くなる。
そのようなときはマージ処理をして途中の更新履歴をタグに集約し、木を浅くする。
目安として「木の深さがいくつ以上になったらマージする」という判断に使える。
Oracle公式技術記事
こちらも参照すると良い。