Sunteți pe pagina 1din 7

Oracle - Les requtes hirarchiques

Juin 2014
Cet article se base sur des tests et recherches raliss dans la version 8.1.5 d'Oracle.

Introduction
Tout au long de cet article, nous allons nous intresser une structure de donnes permettant de
crer un Forum de discussion, matrialis par la table suivante :
===
SQL> create table messages (
2 id number,
3 id_parent number,
4 titre varchar2(50),
5 auteur varchar2(30),
6 dateheure date,
7 texte long);
Table cre.
SQL> alter table messages add primary key (id);
Table modifie.
SQL> alter table messages modify dateheure default sysdate;
Table modifie.
===
La colonne id_parent contient NULL si le message est le premier message d'un fil de discussion,
sinon elle contient l'id du message auquel le message rpond. La colonne dateheure a pour
valeur par dfaut la date systme du serveur de base de donnes. On pourra donc se permettre
de l'ignorer lors de l'insertion des messages.
Nous n'allons pas nous attarder sur l'enregistrement des messages dans la table (ordre SQL
"insert"). Nous n'allons nous intresser qu' la faon dont les donnes sont lues dans la table,
donc aux ordres SQL "select" qu'il faudra excuter pour obtenir les rsultats escompts.
Voici un exemple de contenu de la table messages :

insert into messages (id, id_parent, titre, auteur, texte)


values (1, NULL, 'Combien d''oeufs dans la pate crpes ?',
'John', 'Quelqu''un sait-il combien il faut d''oeufs ?');
insert into messages (id, id_parent, titre, auteur, texte)
values (2, NULL, 'Sondage : votre marque de lait prfre',
'John', 'Dites-moi quelle est votre marque de lait prfre ?');
insert into messages (id, id_parent, titre, auteur, texte)
values (3,1, 'Re : Combien d''oeufs dans la pate crpes ?',
'Martine', 'Je crois que c''est 2 par personne non ?');
insert into messages (id, id_parent, titre, auteur, texte)
values (4,3, 'C''est srement a', 'John', 'Tu dois avoir raison, merci !');
insert into messages (id, id_parent, titre, auteur, texte)
values (5,2, 'Re : Sondage : votre marque de lait prfre',
'Fifi', 'Moi c''est Lait Blanc');
insert into messages (id, id_parent, titre, auteur, texte)
values (6,2, 'Re : Sondage : votre marque de lait prfre',
'Petrus', 'SuperMilk');
insert into messages (id, id_parent, titre, auteur, texte)
values (7,4, 'Re : C''est srement a', 'Martine', 'De rien ;o)');
insert into messages (id, id_parent, titre, auteur, texte)
values (8,2, 'Re : Sondage : votre marque de lait prfre',
'Fifi', 'Au fait pourquoi ce sondage ?');
insert into messages (id, id_parent, titre, auteur, texte)
values (9,2, 'Re : Sondage : votre marque de lait prfre',
'Enrico', 'Le lait de chvre');
insert into messages (id, id_parent, titre, auteur, texte)
values (10,8, 'Re : Sondage : votre marque de lait prfre',
'John', 'Je suis statisticien de formation et j''ai rien d''autre faire');
insert into messages (id, id_parent, titre, auteur, texte)
values (11, NULL, 'Qui a vu le match de volley hier soir ?',
'Petrus', 'Si qq''un connat le score, merci de nous le donner...');
insert into messages (id, id_parent, titre, auteur, texte)
values (12,10, 'Re : Sondage : votre marque de lait prfre', 'Fifi', 'Ok');
insert into messages (id, id_parent, titre, auteur, texte)
values (13,3, 'Re : Combien d''oeufs dans la pate crpes ?',
'Fifi', 'Oui c''est 2 par personne');

Ce qui nous donne le contenu suivant (par ordre chronologique de cration des messages) :
ID ID_P TITRE AUTEUR HEURE
------ --------------------------------------------- -----------------1 Combien d'oeufs dans la pate crpes ? John 16:58:20
2 Sondage : votre marque de lait prfre John 16:58:37
3 1 Re : Combien d'oeufs dans la pate crpes ? Martine 16:58:51
4 3 C'est srement a
John 16:59:00
5 2 Re : Sondage : votre marque de lait prfre Fifi 16:59:08
6 2 Re : Sondage : votre marque de lait prfre Petrus 16:59:14
7 4 Re : C'est srement a
Martine 16:59:20
8 2 Re : Sondage : votre marque de lait prfre Fifi 16:59:26
9 2 Re : Sondage : votre marque de lait prfre Enrico 16:59:31
10 8 Re : Sondage : votre marque de lait prfre John 16:59:45
11 Qui a vu le match de volley hier soir ? Petrus 16:59:51
12 10 Re : Sondage : votre marque de lait prfre Fifi 16:59:59
13 3 Re : Combien d'oeufs dans la pate crpes ? Fifi 17:00:03
Ainsi : - les deux premiers messages sont des dbuts de fil de discussion - le message ID=3
rpond au message ID=1 car son ID_PARENT=1 - le message ID=13 rpond au message ID=3
car son ID_PARENT=3 - etc...
Notre but est donc d'obtenir une hirarchie de la forme :
ID=1
|-ID=3
| |-ID=4
| | |-ID=7
| |-ID=13
ID=2
|-ID=5
|-ID=6
|-ID=8
| |-ID=10
| | |-ID=12
|-ID=9
ID=11
Le lien entre un message et son parent est bien sr fait avec les colonnes ID et ID_PARENT.
Voici la syntaxe de l'ordre SQL permettant de rcuprer la hirarchie souhaite :

===
SQL> select id, id_parent, titre
2 from messages
3 start with id_parent is null
4 connect by id_parent = prior id;
ID ID_PARENT TITRE
--------- --------- -------------------------------------------------1 Combien d'oeufs dans la pate crpes ?
3 1 Re : Combien d'oeufs dans la pate crpes ?
4 3 C'est srement a
7 4 Re : C'est srement a
13 3 Re : Combien d'oeufs dans la pate crpes ?
2 Sondage : votre marque de lait prfre
5 2 Re : Sondage : votre marque de lait prfre
6 2 Re : Sondage : votre marque de lait prfre
8 2 Re : Sondage : votre marque de lait prfre
10 8 Re : Sondage : votre marque de lait prfre
12 10 Re : Sondage : votre marque de lait prfre
9 2 Re : Sondage : votre marque de lait prfre
11 Qui a vu le match de volley hier soir ?
13 ligne(s) slectionne(s).
===
Notre objectif est atteint : nous avons les messages dans le bon ordre. Une requte hirarchique
permet donc de trier des enregistrements en utilisant des notions d'arborescence interenregistrement.

La pseudo-colonne Level
Dans une hirarchie, on peut avoir un lment A qui a pour enfant un lment B, qui lui-mme a
pour enfant un lment C, etc... On peut alors dire que l'lment C est au niveau n+2 par rapport
au niveau n de l'lment A. Afin de mieux voir la profondeur de hirarchie, nous allons utiliser la
pseudo-colonne LEVEL, qui permet de savoir quel niveau hirarchique on se trouve :

===
SQL> select level, titre, auteur
2 from messages
3 start with id_parent is null
4 connect by id_parent = prior id;
LEVEL TITRE
AUTEUR
--------- -------------------------------------------------- --------1 Combien d'oeufs dans la pate crpes ? John
2 Re : Combien d'oeufs dans la pate crpes ? Martine
3 C'est srement a
John
4 Re : C'est srement a
Martine
3 Re : Combien d'oeufs dans la pate crpes ? Fifi
1 Sondage : votre marque de lait prfre John
2 Re : Sondage : votre marque de lait prfre Fifi
2 Re : Sondage : votre marque de lait prfre Petrus
2 Re : Sondage : votre marque de lait prfre Fifi
3 Re : Sondage : votre marque de lait prfre John
4 Re : Sondage : votre marque de lait prfre Fifi
2 Re : Sondage : votre marque de lait prfre Enrico
1 Qui a vu le match de volley hier soir ? Petrus
13 ligne(s) slectionne(s).
===
Pour plus de clart, nous allons faire prcder chaque titre d'un nombre d'espaces gal au level
qui lui correspond. Cela gnrera une indentation du plus bel effet !

===
SQL>
1 select id, id_parent, rpad(' ', level-1) || titre as titre, auteur
2 from messages
3 start with id_parent is null
4 connect by id_parent = prior id;
ID ID_PARENT TITRE
AUTEUR
--- --------- ------------------------------------------------------ ---------1 Combien d'oeufs dans la pate crpes ? John
3 1 Re : Combien d'oeufs dans la pate crpes ? Martine
4 3 C'est srement a John
7 4 Re : C'est srement a Martine
13 3 Re : Combien d'oeufs dans la pate crpes ? Fifi
2 Sondage : votre marque de lait prfre John
5 2 Re : Sondage : votre marque de lait prfre Fifi
6 2 Re : Sondage : votre marque de lait prfre Petrus
8 2 Re : Sondage : votre marque de lait prfre Fifi
10 8 Re : Sondage : votre marque de lait prfre John
12 10 Re : Sondage : votre marque de lait prfre Fifi
9 2 Re : Sondage : votre marque de lait prfre Enrico
11 Qui a vu le match de volley hier soir ? Petrus

13 ligne(s) slectionne(s).
===
Nous venons donc de voir quoi peut servir une requte hirarchique. Parmis les applications
possible de cet outil puissant : - les forums avec fil de discussion (notre exemple) - hirarchie
d'un groupe de personnes (chefs de service - employs) - gestion de catgories et souscatgories pour organiser des informations - ...

Quelques prcisions sur la syntaxe des requtes


hirarchiques
La clause START WITH permet d'indiquer la condition qui dtermine quels enregistrements sont
au niveau 1 (aucun enregistrement au-dessus d'eux dans la hirarchie). Si on n'avait voulu lister
que les fils de discussion initis par John, avec leurs rponses, voici la requte qu'il aurait fallu
excuter :

===
SQL>
1 select id, id_parent, rpad(' ', level-1) || titre as titre, auteur
2 from messages
3 start with id_parent is null and auteur = 'John'
4* connect by id_parent = prior id
ID ID_PARENT TITRE
AUTEUR
--- --------- ------------------------------------------------------ ---------1 Combien d'oeufs dans la pate crpes ? John
3 1 Re : Combien d'oeufs dans la pate crpes ? Martine
4 3 C'est srement a John
7 4 Re : C'est srement a Martine
13 3 Re : Combien d'oeufs dans la pate crpes ? Fifi
2 Sondage : votre marque de lait prfre John
5 2 Re : Sondage : votre marque de lait prfre Fifi
6 2 Re : Sondage : votre marque de lait prfre Petrus
8 2 Re : Sondage : votre marque de lait prfre Fifi
10 8 Re : Sondage : votre marque de lait prfre John
12 10 Re : Sondage : votre marque de lait prfre Fifi
9 2 Re : Sondage : votre marque de lait prfre Enrico
12 ligne(s) slectionne(s).
===
Le 13me et dernier message n'a pas t slectionn car il ne fait pas partie d'un fil de
discussion initi par John. Les requtes hirarchiques sont donc non seulement un moyen de
trier les enregistrements, mais aussi un moyen de slectionner des enregistrements (mme sans
utilisation de la clause where).
La clause CONNECT BY permet d'indiquer la condition qui lie un enregistrement son
enregistrement pre. "connect by id_parent = prior id" doit se lire "la relation pre-fils entre deux
enregistrements est dfinie par le fait que la colonne id_parent de l'enregistrement fils est gale
la colonne id de l'enregistrement pre" (c'est le mot cl PRIOR qui indique que l'on fait
rfrence au pre).
Article crit par Tittom
Ce document intitul Oracle - Les requtes hirarchiques issu de CommentCaMarche
(www.commentcamarche.net) est mis disposition sous les termes de la licence Creative Commons. Vous pouvez
copier, modifier des copies de cette page, dans les conditions fixes par la licence, tant que cette note apparat
clairement.

S-ar putea să vă placă și