Иерархический запрос - PullRequest
2 голосов
/ 18 сентября 2009

Я надеюсь, что смогу объяснить проблему, которая озадачивает меня. У меня есть следующий набор иерархических данных (это всего лишь подмножество 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

Обход должен быть остановлен, когда я сталкиваюсь с записью EXAM = 'N'.

Мне нужно что-то вроде предложения 'stop with'.

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

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

Ответы [ 2 ]

4 голосов
/ 18 сентября 2009

Роберт,

Вы можете сделать это, добавив «exam = 'J'" к выражению connect by:

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 голосов
/ 18 сентября 2009

Похоже, что простой запрос, который получает запрошенный элемент, и это '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, поэтому я не могу проверить, работает ли он, но из того, что я понимаю о синтаксисе и о том, что я только что погуглил, похоже, что он будет работать.

...