2009-09-18 8 views
2

J'espère que je suis en mesure d'expliquer le problème qui me laisse perplexe. J'ai l'ensemble de données hiérarchique suivante (ce qui est juste sous-ensemble de 34K dossiers)Hierarchical Query

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

Ceci est une représentation de l'arbre

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

Ce que je besoin est une liste de tous les dossiers avec examen = N et l'examen sous-jacent = 'J' enregistrements, qui peuvent être imbriqués.

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

Ça me donne

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

Mais ce que je dois est

TUDA12802 TUDA12982   N 
TUDA12982 TUDA12984   J 
TUDA12984 TUDA999   J 

Le déplacement doit arrêter quand je rencontre un EXAMENS = enregistrement 'N'.

J'ai besoin de quelque chose comme une clause '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; 

Comment cela peut-il être fait?

Répondre

4

Robert,

Vous pouvez le faire en ajoutant "examen = 'J'" à la connexion par article:

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. 

Cordialement, Rob .

+0

C'est tout. Tellement simple et élégant. Je pensais avoir rencontré un problème vraiment difficile. Merci beaucoup. Je ne sais pas ce que je veux dire. (Johan Cruijff) –

0

Sons comme une simple requête qui obtient l'élément demandé et il y a des enfants « J » est ce que vous voulez, donc ne serait pas ce travail:

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; 

Je ne je peux pas Oracle afin de ne pas tester si cela fonctionne, mais d'après ce que je comprends de la syntaxe et ce que je viens de googler, il semble que cela fonctionnerait.

+0

Cela donne aussi les enregistrements: TUDA12983 \t TUDA15322 \t J TUDA12983 \t TUDA15323 \t J Ce sont Childs d'un examen = dossiers 'N' et l'examen des dossiers = 'N' ne doivent pas être parcouraient. –