1

start with 、 connect by ステートメントを使用してデータを再帰的に取得しています。すべての親子を取得していますが、各子の最後の親を取得したいだけです。たとえば、次のデータがあります

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;

任意のルートに対してより一般的なソリューションが必要な場合は、これが役立つ場合があります

親をnullにすることはできません。

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 に答える