Bonjour,

je fais appel a vous pour un probleme sur lequel je coince depuis plusieurs semaines sous oracle 9i (je suis aussi interesse pour des solutions autres sous 10g a titre de culture generale):

- je cherche a remonter les branches completes dont chaque noeud a un statut donne (ici par exemple 2) et dont le dernier element de la branche a un type donne (ici par exemple 3)

ce qui revient a dire, que dans l arborescence:
1/ j elague toutes les branches dont le statut des noeuds est different de 2
2/ j elague toutes les branches situees sous les elements ayant un type egal a 3
3/ j elague toutes les branches ne possedant pas d element de type egal a 3

Avec le jeu de donnees suivantes:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
DROP TABLE TEST;
 
CREATE TABLE TEST ( 
  ID NUMBER
, ETATOBJET NUMBER
, NOM NVARCHAR2(25)
, PARENT NUMBER
, TYPE NUMBER
, constraints PK_TEST PRIMARY KEY (ID) 
);
COMMIT;
 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 1, 2, '1', NULL, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 2, 2, '2', NULL, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 3, 2, '3', NULL, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 4, 2, '4', NULL, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 5, 0, '5', NULL, 0); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 6, 0, '1.1', 1, 0); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 7, 2, '1.2', 1, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 8, 2, '1.2.1', 7, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 9, 2, '2.1', 2, 3); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 10, 0, '2.2', 2, 0); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 11, 2, '2.1.1', 9, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 12, 2, '3.1', 3, 3); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 13, 2, '3.2', 3, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 14, 2, '3.3', 3, 3); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 15, 2, '3.3.1', 14, 0); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 16, 2, '4.1', 4, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 17, 0, '4.1.1', 16, 0); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 18, 2, '4.1.1.1', 17, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 19, 0, '4.2', 4, 2); 
INSERT INTO TEST ( ID, ETATOBJET, NOM, PARENT, TYPE ) VALUES ( 20, 2, '4.2.1', 19, 3); 
COMMIT;
j arrive a appliquer la regle 1/:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
SELECT 
      ID
    , '"' || sys_connect_by_path(NOM, ' / ') || '"' AS path
    , NOM
    , ETATOBJET
    , PARENT
    , TYPE 
FROM 
    test 
start WITH (parent IS NULL AND ETATOBJET = 2)
connect BY (prior id = parent AND ETATOBJET = 2)
qui donne le resultat
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
ID	PATH			NOM	ETAT	PARENT	TYPE
1	" / 1"			1	2	(null)	2
7	" / 1 / 1.2"		1.2	2	1	2
8	" / 1 / 1.2 / 1.2.1"	1.2.1	2	7	2
2	" / 2"			2	2	(null)	2
9	" / 2 / 2.1"		2.1	2	2	3
11	" / 2 / 2.1 / 2.1.1"	2.1.1	2	9	2
3	" / 3"			3	2	(null)	2
12	" / 3 / 3.1"		3.1	2	3	3
13	" / 3 / 3.2"		3.2	2	3	2
14	" / 3 / 3.3"		3.3	2	3	3
15	" / 3 / 3.3 / 3.3.1"	3.3.1	2	14	0
4	" / 4"			4	2	(null)	2
16	" / 4 / 4.1"		4.1	2	4	2
mais impossible d arriver a "elaguer" (via une seule requete) les elements qui correspondent a la regle 3/ (ID 1, 7, 8, 13, 4, 16) ni ceux de la regle 2/ (ID 11, 15) pour avoir le resultat attendu suivant:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
ID	PATH			NOM	ETAT	PARENT	TYPE
2	" / 2"			2	2	(null)	2
9	" / 2 / 2.1"		2.1	2	2	3
3	" / 3"			3	2	(null)	2
12	" / 3 / 3.1"		3.1	2	3	3
14	" / 3 / 3.3"		3.3	2	3	3
Auriez vous une idee de comment faire ??
Par avance merci

PS: il peut y avoir des soucis (erreur ORA-600) avec les requetes "Connect by" imbriquees, une astuce est de mettre le hint "/*+ NO_FILTERING */" devant chaque SELECT de la requete