我有一个像下面这样的分层表。我想根据FLAG
值设置CODE
属性。可能的代码值为R
,NR
,RN
和NF
。如果相应的代码值与父代的值一致,则FLAG
将设置为'Y'
,
if parent.code = 'R' and child.code = 'R' then flag = 'Y'
if parent.code = 'NR' and child.code = 'NR' then flag = 'Y'
if parent.code = 'RNR' and child.code = 'R' or 'NR', then flag = 'Y'.
这是我的表:
create table My_BOM(assign_Id varchar2(50) not null primary key,
parent_assign_Id varchar2(50) references My_BOM(assign_Id),
code varchar2(50) not null,
flag varchar2(1) default 'Y');
insert into my_bom values ('T1',null,'RNR','Y');
insert into my_bom values ('T2','T1','R','Y');
insert into my_bom values ('T3','T2','NR','Y');
insert into my_bom values ('T4','T3','R','Y');
insert into my_bom values ('T5','T1','NF','Y');
insert into my_bom values ('T6','T5','R','Y');
insert into my_bom values ('T7','T1','NR','Y');
insert into my_bom values ('T8','T7','RNR','Y');
insert into my_bom values ('T9','T8','R','Y');
insert into my_bom values ('T10','T1','RNR','Y');
如何设置FLAG?这是我尝试的方式,但是这个查询也返回了我不想要的T9记录,因为链条在两者之间被打破,即它们在CODE
的顶层中是不一致的。所以,T9不应该作为结果的一部分。
select connect_by_root(assign_Id), assign_Id desc_assign_Id, code, flag
from my_bom
where
--exists (select null from my_bom mb where mb.parent_assign_Id = prior my_bom.assign_Id
--connect by mb.parent_assign_Id = prior mb.assign_Id) and
DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL) = PRIOR DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL)
start with parent_assign_Id is null
connect by parent_assign_Id = prior assign_Id
order by desc_assign_Id;
"bind_var"
可以是'R'
或'NR'
这是SQL小提琴:http://sqlfiddle.com/#!4/009ad/2/0
答案 0 :(得分:1)
我不确定我是否理解正确,但您可以将条件移至connect by
子句以过滤整个层次结构中的不一致(与最后一对父/子夫妇相比)
select connect_by_root(assign_Id), assign_Id desc_assign_Id, code, flag
from my_bom
connect by parent_assign_Id = prior assign_Id
and DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL) = PRIOR DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL)
start with parent_assign_Id is null
order by desc_assign_Id;
如果您不想要root,也可以添加where parent_assign_Id is not null
:
select connect_by_root(assign_Id), assign_Id desc_assign_Id, code, flag
from my_bom
where parent_assign_Id is not null
connect by parent_assign_Id = prior assign_Id
and DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL) = PRIOR DECODE( CODE,
'R', 'R', 'NR', 'NR', 'RNR',
:bind_var, NULL)
start with parent_assign_Id is null
order by desc_assign_Id;
复合connect by
条件应该适用于Oracle 10g,我只测试了11g