teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

参考サイトとサンプルを追記

2020/06/12 01:54

投稿

toyotaku
toyotaku

スコア103

answer CHANGED
@@ -1,3 +1,52 @@
1
1
  階層問い合わせをご検討ください。
2
2
 
3
- [SQLの抽出結果を階層構造で表示するテクニック](https://www.atmarkit.co.jp/ait/articles/0507/28/news131.html)
3
+ [SQLの抽出結果を階層構造で表示するテクニック](https://www.atmarkit.co.jp/ait/articles/0507/28/news131.html)
4
+
5
+ [図でイメージするOracle DatabaseのSQL全集 第6回 階層問い合わせ Oracle SQLの各機能をイメージ図を交えて解説](https://www.oracle.com/jp/technical-resources/article/otnj-sql-image6.html)
6
+
7
+ 自レコードよりも上位の階層でかつフラグが1になっている階層の名称を取得
8
+ 各レコードをルート(最上位)とし、
9
+ 上位レコードのPARENT_IDとIDが一致する下位レコードを問い合わせ、
10
+ FLAGが1のレコードの名前を取得する
11
+ ```SQL
12
+ SELECT
13
+ CONNECT_BY_ROOT(ID) AS ROOT_ID
14
+ , CONNECT_BY_ROOT(NAME) AS ROOT_NAME
15
+ , CASE
16
+ WHEN
17
+ FLAG = 1
18
+ AND CONNECT_BY_ROOT(ID) != ID --自レコードのフラグが1の場合は表示しない
19
+ THEN NAME
20
+ ELSE NULL
21
+ END AS FLAG1_NAME
22
+ FROM
23
+ TBL
24
+ WHERE
25
+ CONNECT_BY_ISLEAF = 1 -- LEAF行だけを取得
26
+ CONNECT BY
27
+ PRIOR PARENT_ID = ID -- PARENT_IDで下位レコードのIDと紐づける
28
+ AND PRIOR FLAG != 1 -- FLAGが1なら下位レコードを問い合わせない
29
+ ORDER BY
30
+ CONNECT_BY_ROOT(ID)
31
+ ```
32
+
33
+ 階層レベルが2の階層の名称を取得
34
+ 各レコードをルート(最上位)とし、
35
+ 上位レコードのPARENT_IDとIDが一致する下位レコードを問い合わせ、
36
+ 親レコードのPARENT_IDがNULLではないレコードまで問い合わせる
37
+ ※親レコードのPARENT_IDがNULL = 階層レベル2
38
+ ```SQL
39
+ SELECT
40
+ CONNECT_BY_ROOT(ID) AS ROOT_ID
41
+ , CONNECT_BY_ROOT(NAME) AS ROOT_NAME
42
+ , NVL2(PARENT_ID,NAME,NULL) LEVEL2_NAME
43
+ FROM
44
+ TBL
45
+ WHERE
46
+ CONNECT_BY_ISLEAF = 1 -- LEAF行だけを取得
47
+ CONNECT BY
48
+ PRIOR PARENT_ID = ID -- PARENT_IDで下位レコードのIDと紐づける
49
+ AND PARENT_ID IS NOT NULL -- 親レコードのPARENT_IDがNULLは対象にしない(=レベル2)
50
+ ORDER BY
51
+ CONNECT_BY_ROOT(ID)
52
+ ```