假设我在Oracle数据库中具有以下表结构,其中PARENT引用同一表中的另一行。
id | parent
1 | null
2 | 1
3 | 2
4 | 3
5 | null
6 | 5
7 | 6
我该如何查询,以便每一行都让我知道序列的结尾。那就是我希望看到的最终结果:
id | end_parent
1 | 4
2 | 4
3 | 4
4 | 4
5 | 7
6 | 7
7 | 7
答案 0 :(得分:2)
以下查询显示了在Oracle 12c上测试所需的结果:
with
x (id, parent, origin, generation) as (
select id, parent, id, 1 from my_table where parent is null
union all
select t.id, t.parent, x.origin, x.generation + 1
from my_table t
join x on t.parent = x.id
),
y (id, parent, generation, origin, rn) as (
select id, parent, generation, origin,
row_number() over(partition by origin order by generation desc) as rn
from x
),
z (id, origin) as (
select id, origin from y where rn = 1
)
select x.id, z.id as end_parent
from x
join z on x.origin = z.origin
order by x.id
结果:
ID END_PARENT
-- ----------
1 4
2 4
3 4
4 4
5 7
6 7
7 7
作为参考,这是我使用的数据:
create table my_table (
id int,
parent int
);
insert into my_table (id, parent) values (1, null);
insert into my_table (id, parent) values (2, 1);
insert into my_table (id, parent) values (3, 2);
insert into my_table (id, parent) values (4, 3);
insert into my_table (id, parent) values (5, null);
insert into my_table (id, parent) values (6, 5);
insert into my_table (id, parent) values (7, 6);
答案 1 :(得分:1)
使用connect by
语法,并使用sys_connect_by_path
创建路径。路径的最后一个值为end_parent
。使用connect_by_root
获取根父级的id
。基于该组,将每个组的最大值作为end_parent
。最后,将分组添加到每一行。
with id_paths as
(
select
t.id,
substr(sys_connect_by_path(t.id,'>'),2,length(sys_connect_by_path(t.id,'>'))-1) as id_path,
connect_by_root t.id as parent_group
from my_table t
connect by prior t.id = t.parent
start with t.parent is null
),
end_parents as
(
select
ip.parent_group,
max(substr(ip.id_path, instr(ip.id_path,'>',-1)+1, length(ip.id_path))) as end_parent
from id_paths ip
group by ip.parent_group
)
select
ip.id,
ep.end_parent
from id_paths ip
inner join end_parents ep on ep.parent_group = ip.parent_group
order by ip.id;
输出
| ID | END_PARENT |
|----|------------|
| 1 | 4 |
| 2 | 4 |
| 3 | 4 |
| 4 | 4 |
| 5 | 7 |
| 6 | 7 |
| 7 | 7 |
答案 2 :(得分:0)
根据此处https://docs.oracle.com/database/121/SQLRF/queries003.htm的Oracle文档,您应该能够做到:
SELECT COALESCE(CONNECT_BY_ROOT parent, id) id,
id end_parent
FROM my_table
WHERE CONNECT_BY_ISLEAF = 1
CONNECT BY PRIOR id = parent
ORDER BY id