Oracle Иерархический вопрос (Найти шаг братьев и сестер) - PullRequest
0 голосов
/ 30 ноября 2018

Я работаю над проблемой, когда, начиная с любого «листа» или ребенка, я могу найти братьев и сестер этого ребенка и пасынков.Чтобы проиллюстрировать лучший пример, если у родителя A есть два ребенка, и у него один ребенок с родителем B, а у родителя B два ребенка, один с родителем A и один с родителем C, а у родителя c есть два других потомка, с которыми нет общего доступа.родитель Б, как мне сообщить обо всех детях?Я пытался использовать рекурсивный и иерархический запрос, но, похоже, не могу сделать это правильно.Ниже приведена структура таблицы и значения и мои попытки до сих пор.

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';

1 Ответ

0 голосов
/ 30 ноября 2018

Вот простое (но, возможно, не очень производительное) решение, начиная с данного родителя:

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, то вы должны переключить 0 и 1 для значенийmod(level, 2) в состоянии connect by;остальное без изменений.

...