Reputation: 8915
I hope I'm able to explain the problem that is puzzeling me. I have the following hierarchical data set (this is just subset of 34K records)
PARENT_ID CHILD_ID EXAM
TUDA12802 TUDA12982 N
TUDA12982 TUDA12984 J
TUDA12984 TUDA999 J
TUDA12982 TUDA12983 N
TUDA12983 TUDA15322 J
TUDA12983 TUDA15323 J
This is a representation of the tree
TUDA12982 N
- TUDA12984 J
-- TUDA999 J
- TUDA12983 N
-- TUDA15322 J
-- TUDA15323 J
What I need is a list of all records with exam=N and the underlying exam = 'J' records, which can be nested.
select *
from test1
connect by prior child_id = parent_id
start with child_id = 'TUDA12982'
order siblings by child_id;
Gives me
PARENT_ID CHILD_ID EXAM
TUDA12802 TUDA12982 N
TUDA12982 TUDA12984 J
TUDA12984 TUDA999 J
TUDA12982 TUDA12983 N
TUDA12983 TUDA15323 J
TUDA12983 TUDA15322 J
But what I need is
TUDA12802 TUDA12982 N
TUDA12982 TUDA12984 J
TUDA12984 TUDA999 J
The traversing needs to stop when I encounter a EXAM = 'N' record.
I need something like a 'stop with' clause.
select *
from test1
connect by prior child_id = parent_id
start with child_id = 'TUDA12982'
stop with exam = 'N'
order siblings by child_id;
How can this be done?
Upvotes: 2
Views: 1440
Reputation: 17705
Robert,
You can do this by adding "exam = 'J'" to the connect by clause:
SQL> create table test1(parent_id,child_id,exam)
2 as
3 select 'TUDA12802', 'TUDA12982', 'N' from dual union all
4 select 'TUDA12982', 'TUDA12984', 'J' from dual union all
5 select 'TUDA12984', 'TUDA999', 'J' from dual union all
6 select 'TUDA12982', 'TUDA12983', 'N' from dual union all
7 select 'TUDA12983', 'TUDA15322', 'J' from dual union all
8 select 'TUDA12983', 'TUDA15323', 'J' from dual
9 /
Tabel is aangemaakt.
SQL> select parent_id
2 , child_id
3 , exam
4 , level
5 , lpad(' ',2*level) || sys_connect_by_path(parent_id||'-'||child_id,'/') scbp
6 from test1
7 start with exam = 'N'
8 connect by prior child_id = parent_id
9 and exam = 'J'
10 /
PARENT_ID CHILD_ID E LEVEL SCBP
--------- --------- - ------ ----------------------------------------------------------------------
TUDA12802 TUDA12982 N 1 /TUDA12802-TUDA12982
TUDA12982 TUDA12984 J 2 /TUDA12802-TUDA12982/TUDA12982-TUDA12984
TUDA12984 TUDA999 J 3 /TUDA12802-TUDA12982/TUDA12982-TUDA12984/TUDA12984-TUDA999
TUDA12982 TUDA12983 N 1 /TUDA12982-TUDA12983
TUDA12983 TUDA15322 J 2 /TUDA12982-TUDA12983/TUDA12983-TUDA15322
TUDA12983 TUDA15323 J 2 /TUDA12982-TUDA12983/TUDA12983-TUDA15323
6 rijen zijn geselecteerd.
Regards, Rob.
Upvotes: 4
Reputation: 16884
Sounds like a simple query that gets the requested item and it's 'J' children is what you want, so wouldn't this work:
select *
from test1
where child_id = 'TUDA12982'
or exam = 'J'
connect by prior child_id = parent_id
start with child_id = 'TUDA12982'
order siblings by child_id;
I don't have Oracle so I can't test if that works, but from what I understand of the syntax and what I just Googled it looks like it would work.
Upvotes: 0