我正在尝试查询代表某些分层数据的(大)Oracle 9表。父项具有自己的ID作为父ID。作为一个例子;
ID PARENTID
----- --------
1 1
2 1
3 2
4 2
5 3
6 6
7 6
8 6
9 4
10 10
我想要一个返回每个ID的查询,以及该ID的最终Parent,所以继续我的例子
ID UlitimateParent
---- ----
1 1
2 1
3 1
4 1
5 1
6 6
7 6
8 6
9 1
10 10
我看过一些使用Connect By的例子,但似乎无法让它工作。有什么想法吗?
答案 0 :(得分:3)
在10g +中,您将使用CONNECT_BY_ROOT
函数:
SQL> with data as (
2 SELECT 1 id, 1 parent_id FROM DUAL
3 UNION ALL SELECT 2 , 1 FROM DUAL
4 UNION ALL SELECT 3 , 2 FROM DUAL
5 UNION ALL SELECT 4 , 2 FROM DUAL
6 UNION ALL SELECT 5 , 3 FROM DUAL
7 UNION ALL SELECT 6 , 6 FROM DUAL
8 UNION ALL SELECT 7 , 6 FROM DUAL
9 UNION ALL SELECT 8 , 6 FROM DUAL
10 UNION ALL SELECT 9 , 4 FROM DUAL
11 UNION ALL SELECT 10, 10 FROM DUAL
12 )
13 SELECT id, connect_by_root(id) ultimate_parent_id
14 FROM data
15 START WITH id = parent_id
16 CONNECT BY parent_id = PRIOR id AND id != PRIOR id ;
ID ULTIMATE_PARENT_ID
--- ------------------
1 1
2 1
3 1
5 1
4 1
9 1
6 6
7 6
8 6
10 10
在9i中,您可以使用SYS_CONNECT_BY_PATH
(使用适当的子字符串):
SQL> with data as (
2 SELECT 1 id, 1 parent_id FROM DUAL
3 UNION ALL SELECT 2 , 1 FROM DUAL
4 UNION ALL SELECT 3 , 2 FROM DUAL
5 UNION ALL SELECT 4 , 2 FROM DUAL
6 UNION ALL SELECT 5 , 3 FROM DUAL
7 UNION ALL SELECT 6 , 6 FROM DUAL
8 UNION ALL SELECT 7 , 6 FROM DUAL
9 UNION ALL SELECT 8 , 6 FROM DUAL
10 UNION ALL SELECT 9 , 4 FROM DUAL
11 UNION ALL SELECT 10, 10 FROM DUAL
12 )
13 SELECT id, sys_connect_by_path(id, '->') path
14 FROM data
15 START WITH id = parent_id
16 CONNECT BY parent_id = PRIOR id
17 AND id != PRIOR id;
ID PATH
---------- --------------------
1 ->1
2 ->1->2
3 ->1->2->3
5 ->1->2->3->5
4 ->1->2->4
9 ->1->2->4->9
6 ->6
7 ->6->7
8 ->6->8
10 ->10
答案 1 :(得分:2)
由于你的问题,我刚学会了这个:)
您可以使用
replace(sys_connect_by_path(decode(level, 1, id), '~'), '~')
替换10g之前的connect_by_root函数。
with data1 as (
SELECT 1 id, 1 parent_id FROM DUAL
UNION ALL SELECT 2 , 1 FROM DUAL
UNION ALL SELECT 3 , 2 FROM DUAL
UNION ALL SELECT 4 , 2 FROM DUAL
UNION ALL SELECT 5 , 3 FROM DUAL
UNION ALL SELECT 6 , 6 FROM DUAL
UNION ALL SELECT 7 , 6 FROM DUAL
UNION ALL SELECT 8 , 6 FROM DUAL
UNION ALL SELECT 9 , 4 FROM DUAL
UNION ALL SELECT 10, 10 FROM DUAL
)
SELECT id, replace(sys_connect_by_path(decode(level,
1, id), '~'), '~')
ultimate_parent_id
FROM data1
START WITH id = parent_id
CONNECT BY parent_id = PRIOR id AND id != PRIOR id ;
ID PATH
--------------
1 1
2 1
3 1
5 1
4 1
9 1
6 6
7 6
8 6
10 10