2009-09-18 2 views
2

Надеюсь, я смогу объяснить проблему, которая меня озадачивает. У меня есть следующий иерархический набор данных (это только подмножество 34K записей)Иерархический запрос

PARENT_ID CHILD_ID   EXAM 
TUDA12802 TUDA12982   N 
TUDA12982 TUDA12984   J  
TUDA12984 TUDA999   J 
TUDA12982 TUDA12983   N 
TUDA12983 TUDA15322   J 
TUDA12983 TUDA15323   J 

Это представление дерева

TUDA12982 N 
- TUDA12984 J 
-- TUDA999 J 
- TUDA12983 N 
-- TUDA15322 J 
-- TUDA15323 J 

Что мне нужно, это список всех записей с экзаменом = N и базовый экзамен = 'J' записи, которые могут быть вложенными.

select * 
from test1 
connect by prior child_id = parent_id 
start with child_id = 'TUDA12982' 
order siblings by child_id; 

дает мне

PARENT_ID  CHILD_ID   EXAM 
TUDA12802 TUDA12982   N 
TUDA12982 TUDA12984   J  
TUDA12984 TUDA999   J 
TUDA12982 TUDA12983   N 
TUDA12983 TUDA15323   J 
TUDA12983 TUDA15322   J 

Но что мне нужно

TUDA12802 TUDA12982   N 
TUDA12982 TUDA12984   J 
TUDA12984 TUDA999   J 

проникающего должен остановиться, когда я сталкиваюсь с ЭКЗАМЕН = запись 'N'.

Мне нужно что-то вроде предложения «остановиться с».

select * 
from test1 
connect by prior child_id = parent_id 
start with child_id = 'TUDA12982' 
stop with exam = 'N' 
order siblings by child_id; 

Как это можно сделать?

ответ

4

Роберт,

Вы можете сделать это, добавив "экзамен =" J" к подключению по статье:

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. 

С уважением, Роб.

+0

Вот и все. Так просто и элегантно. Я думал, что столкнулся с действительно сложной проблемой. Большое спасибо. Je gaat het pas zien als je het doorhebt. (Йохан Кройдж) –

0

Похоже, простой запрос, который получает требуемый пункт и это дети «J» является то, что вы хотите, так что бы не эта работа:

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; 

Я не Oracle, так что я не могу если это сработает, но из того, что я понимаю в синтаксисе, и что я просто Google, похоже, это сработает.

+0

Это также дает запись: TUDA12983 \t \t TUDA15322 ямайскому TUDA12983 \t \t TUDA15323 J Этим Чайлдсы из экзамена = записи 'N' и экзамен = записи 'N' не должны быть пройдены. –

Смежные вопросы