我在Oracle11g中有一个像(id,parent_id)这样的结构的表。
id parent_id
---------------
1 (null)
2 (null)
3 1
4 3
5 3
6 2
7 2
我想查询它以获得与这些id中的每一个分层链接的所有行,因此结果应为:
root_id id parent_id
------------------------
1 3 1
1 4 3
1 5 3
2 6 2
2 7 2
3 4 3
3 5 3
我已经在connect by
和start with
挣扎了很长一段时间了,我所能得到的只是我想要的结果的一小部分,例如:
select connect_by_root(id) root_id, id, parent_id from my-table
start with id=1
connect by prior id = parent_id
我不想使用任何for
循环来获得完整的结果。
任何想法?
祝你好运, JérômeLefrère
PS:在第一次回答后编辑,注意到我忘记了一些我想要的结果......
答案 0 :(得分:3)
您发布的查询缺少from
子句,并在connect_by_root
之外留下了下划线,但我认为这些不是您问题的根源。
以下查询为您提供了您正在寻找的结果:
select * from (
select connect_by_root(id) root_id, id, parent_id
from test1
start with parent_id is null
connect by prior id = parent_id)
where root_id <> id
核心问题是您指定了一个特定的值来开始,而是指定一种识别根行的方法。将id = 1
更改为parent_id is null
可以返回表格的全部内容。
我还添加了外部查询来过滤结果集中的根行,这在您的问题中未提及,但显示在您想要的结果中。
评论回复:
在提供的版本中,您确实获得id = 3
的后代,但不是3
是根的方式。这是因为我们从绝对的根开始。解决这个问题很容易,只需省略start with
子句:
SELECT *
FROM
(SELECT connect_by_root(id) root_id,
id,
parent_id
FROM test1
CONNECT BY
PRIOR id = parent_id)
WHERE root_id <> id
答案 1 :(得分:2)
试试这个:
select connect_by_root(id) root_id, id, parent_id
from your_table
start with parent_id is null
connect by prior id = parent_id
答案 2 :(得分:0)
它将为您提供所需的确切结果:
select connect_by_root(id) as root, id, parent_id
from test1
connect by prior id=parent_id
start with parent_id is not null;