1

我正在使用 start with , connect by statement 来递归地获取数据,我得到了所有的父母 - 孩子,但我只想得到每个孩子的最终父母。例如,我有以下数据

child --> parent
a ------> b,
b ------> c,
c ------> d,
c ------> e

所以我只想要输出

a --> d,
and a --> e

我的查询是

SELECT  LEVEL, cp.child, cp.parent FROM child_parent cp
CONNECT BY nocycle PRIOR cp.parent= cp.child
START WITH cp.child= a

任何机构都可以帮我解决这个问题。

4

1 回答 1

0

目前尚不清楚您是要对根“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;

如果您想为任何根提供更通用的解决方案,这可能会有所帮助

编辑,因为父不能为空:

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;
于 2011-01-20T23:09:34.187 回答