Неясно, хотите ли вы жесткий код ваш корень 'a' (что делает решение немного проще) или вы хотите иметь более общее решение для нескольких корней. Если исходить из первого, то это может заставить вас начать:
create table child_parent (
parent varchar2(2),
child varchar2(2)
);
insert into child_parent values (null, 'a');
insert into child_parent values ( 'a', 'b');
insert into child_parent values ( 'b', 'c');
insert into child_parent values ( 'c', 'd');
insert into child_parent values ( 'c', 'e');
insert into child_parent values (null, 'k');
insert into child_parent values ( 'k', 'l');
insert into child_parent values ( 'l', 'm');
insert into child_parent values ( 'l', 'n');
with choose_root_here as (
select 'a' as root from dual
)
select
choose_root_here.root || '->' || child from
(
select
level lvl,
connect_by_isleaf leaf,
cp.parent,
cp.child
from
child_parent cp
connect by nocycle prior cp.child= cp.parent
start with
cp.child='a'
)
cross join choose_root_here
where
leaf = 1;
Если вы хотите более общее решение для любого root, это может помочь
Редактировать , для родителя не может быть пустым:
select
substr(regexp_replace(path, '##(\w+).*##(\w+)', '\1->\2'),1,30) path
from (
select
level lvl,
substr(sys_connect_by_path(child, '##'),1,20) path,
connect_by_isleaf leaf,
cp.parent,
cp.child
from
child_parent cp
connect by nocycle prior cp.child= cp.parent
start with
cp.parent is null
)
where leaf = 1;