create table 部品(
親 char(1),
子 char(1),
数量 number(1));
insert into 部品 values('A', 'B',2);
insert into 部品 values('B', 'C',3);
insert into 部品 values('C',null,4);
insert into 部品 values('D',null,5);
insert into 部品 values('E', 'F',6);
insert into 部品 values('F',null,7);
insert into 部品 values('E', 'G',8);
insert into 部品 values('G',null,9);
commit;
col 根 for a4
col 親 for a4
col 子 for a4
col 数量 for 99
--■■■Connect_by_Rootを使う方法(10g以降)■■■
select Connect_by_Root 親 as 根,
親,子,数量,
nvl(prior 数量,1) * 数量 as "数量×親の数量"
from 部品 a
start with not exists(select 1 from 部品 b
where b.子 = a.親)
connect by prior 子 = 親;
--■■■sys_connect_by_pathを使う方法(9i以降)(親が可変長文字列の場合)■■■
select
substr(sys_connect_by_path(親,','),2,
decode(instr(substr(sys_connect_by_path(親,','),2),','),
0,Length(substr(sys_connect_by_path(親,','),2)),
instr(substr(sys_connect_by_path(親,','),2),',')-1)) as 根,
親,子,数量,
nvl(prior 数量,1) * 数量 as "数量×親の数量"
from 部品 a
start with not exists(select 1 from 部品 b
where b.子 = a.親)
connect by prior 子 = 親;
--■■■sys_connect_by_pathを使う方法(9i以降)(親が固定長文字列の場合)■■■
select
substr(sys_connect_by_path(親,','),2,1) as 根,
親,子,数量,
nvl(prior 数量,1) * 数量 as "数量×親の数量"
from 部品 a
start with not exists(select 1 from 部品 b
where b.子 = a.親)
connect by prior 子 = 親;
--■■■select句で相関サブクエリを使う方法■■■
select
(select distinct Last_Value(親) over(order by Level
Rows between Unbounded Preceding and Unbounded Following)
from 部品 b
start with b.RowID = a.RowID
connect by prior 親 = 子) as 根,
親,子,数量,
nvl(prior 数量,1) * 数量 as "数量×親の数量"
from 部品 a
start with not exists(select 1 from 部品 b
where b.子 = a.親)
connect by prior 子 = 親;
--■■■select句で相関サブクエリを使わない方法■■■
select b.親 as 根,
a.親,a.子,a.数量,a."数量×親の数量"
from (select aa.親,aa.子,aa.数量,
nvl(prior 数量,1) * 数量 as "数量×親の数量"
from 部品 aa
start with not exists(select 1 from 部品 bb
where bb.子 = aa.親)
connect by prior 子 = 親) a,
(select distinct 親 from 部品 aa
where not exists(select 1 from 部品 bb
where aa.親=bb.子)) b
where a.親 in (select c.親 from 部品 c
start with c.親=b.親
connect by prior c.子=c.親);