Frage

I am having a hierarchical table like below. I want to set the FLAG attribute based on the CODE values. The possible Code values are R, NR, RN and NF. The FLAG will be set to 'Y' iff the corresponding code value is consistent with that of parent i.e

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'.

Here's my table:

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');

How to set the FLAG? This is how I tried but this query also returns the T9 record which I don't want because the chain is broken in between i.e their is inconsistency in the top levels of the CODE. so, T9 should n't come as part of the result.

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" will be either 'R' or 'NR'

Here's the SQL Fiddle:http://sqlfiddle.com/#!4/009ad/2/0

War es hilfreich?

Lösung

I'm not sure if I understand correctly, but you can move the condition to the connect by clause to filter out inconsistencies along the entire hierarchy (versus for the last parent/child couple)

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;

You may also add where parent_assign_Id is not null if you don't want the root :

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;

Compound connect by condition should work with Oracle 10g, I only tested with 11g

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top