Oracle 分层问题(查找继兄弟姐妹)
Oracle Hierarchical Question (Find step siblings)
我正在解决一个问题,从任何 'leaf' 或 child 开始,我可以找到 child 的兄弟姐妹和继兄弟姐妹。举个更好的例子,如果parentA有两个children,和parentB共用一个child,而parentB有两个children,一个与 parent A 共享,一个与 parent C 共享,parent c 还有两个 children 不与 parent B 共享,我如何报告所有 children?我试过使用递归和分层查询,但似乎无法正确使用。以下是 table 结构和值以及我迄今为止的尝试。
create table bw_parents(
parent_id char(1) primary key);
create table bw_children(
child_id number(2),
parent_id char(1),
constraint parent_id_fk FOREIGN KEY (parent_id) references bw_parents
);
insert into bw_parents values('A');
insert into bw_parents values('B');
insert into bw_parents values('C');
insert into bw_parents values('D');
insert into bw_parents values('E');
insert into bw_children values(1,'A');
insert into bw_children values(2,'A');
insert into bw_children values(2,'B');
insert into bw_children values(3,'B');
insert into bw_children values(3,'C');
insert into bw_children values(4,'C');
insert into bw_children values(5,'C');
insert into bw_children values(6,'D');
insert into bw_children values(7,'D');
insert into bw_children values(8,'E');
--hierarchical attempt
select A.parent_id, B.child_id, level
from bw_parents A
join bw_children B ON A.parent_id = B.parent_id
start with A.parent_id = 'B'
connect by nocycle prior B.parent_id = B.parent_id
--recursive with
with r as(
select parent_id, null as child_id
from bw_parents
union all
select A.parent_id parent_id, B.child_id child_id
from bw_parents A
join bw_children B ON A.parent_id = B.parent_id)
select *
from r
where parent_id = 'B';
这是一个从给定父级开始的简单(但可能不是很高效)解决方案:
select distinct child_id
from bw_children
start with parent_id = 'A'
connect by nocycle (mod(level, 2) = 0 and child_id = prior child_id ) or
(mod(level, 2) = 1 and parent_id = prior parent_id)
;
如果必须以child_id
开头,那么在connect by
条件下,mod(level, 2)
的值必须切换0和1;其余不变
我正在解决一个问题,从任何 'leaf' 或 child 开始,我可以找到 child 的兄弟姐妹和继兄弟姐妹。举个更好的例子,如果parentA有两个children,和parentB共用一个child,而parentB有两个children,一个与 parent A 共享,一个与 parent C 共享,parent c 还有两个 children 不与 parent B 共享,我如何报告所有 children?我试过使用递归和分层查询,但似乎无法正确使用。以下是 table 结构和值以及我迄今为止的尝试。
create table bw_parents(
parent_id char(1) primary key);
create table bw_children(
child_id number(2),
parent_id char(1),
constraint parent_id_fk FOREIGN KEY (parent_id) references bw_parents
);
insert into bw_parents values('A');
insert into bw_parents values('B');
insert into bw_parents values('C');
insert into bw_parents values('D');
insert into bw_parents values('E');
insert into bw_children values(1,'A');
insert into bw_children values(2,'A');
insert into bw_children values(2,'B');
insert into bw_children values(3,'B');
insert into bw_children values(3,'C');
insert into bw_children values(4,'C');
insert into bw_children values(5,'C');
insert into bw_children values(6,'D');
insert into bw_children values(7,'D');
insert into bw_children values(8,'E');
--hierarchical attempt
select A.parent_id, B.child_id, level
from bw_parents A
join bw_children B ON A.parent_id = B.parent_id
start with A.parent_id = 'B'
connect by nocycle prior B.parent_id = B.parent_id
--recursive with
with r as(
select parent_id, null as child_id
from bw_parents
union all
select A.parent_id parent_id, B.child_id child_id
from bw_parents A
join bw_children B ON A.parent_id = B.parent_id)
select *
from r
where parent_id = 'B';
这是一个从给定父级开始的简单(但可能不是很高效)解决方案:
select distinct child_id
from bw_children
start with parent_id = 'A'
connect by nocycle (mod(level, 2) = 0 and child_id = prior child_id ) or
(mod(level, 2) = 1 and parent_id = prior parent_id)
;
如果必须以child_id
开头,那么在connect by
条件下,mod(level, 2)
的值必须切换0和1;其余不变