2013-07-02 3 views
2

Étant donné le tableau T_Person (nom, parent) données contenantancêtres oracle dans les requêtes hiérarchiques

 
+--------+--------+ 
| name | parent | 
+--------+--------+ 
| john | peter | 
| peter | ronald | 
| ronald | george | 
| george |  | 
+--------+--------+ 

on peut trouver des relations en utilisant cette requête:

select name, parent, LEVEL 
from T_Person 
connect by prior name = parent 
start with parent is null; 

le résultat serait:

 
+--------+--------+-------+ 
| name | parent | LEVEL | 
+--------+--------+-------+ 
| john | peter | 4  | 
| peter | ronald | 3  | 
| ronald | george | 2  | 
| george |  | 1  | 
+--------+--------+-------+ 

C'est très bien jusqu'à présent. Mais je veux avoir un résultat contenant toutes les relations qui ressemble ainsi:

 
+--------+--------+----------------+ 
| name | parent | relation_level | 
+--------+--------+----------------+ 
| john | peter | 1    | 
| peter | ronald | 1    | 
| ronald | george | 1    | 
| john | ronald | 2    | 
| peter | george | 2    | 
| john | george | 3    | 
+--------+--------+----------------+ 

(relation_level: 1 = père, 2 = grand-père, 3 = grand-père grand et ainsi de suite)

Est-il un moyen rapide pour recevoir ce résultat, autre que sélectionner sur la table entière pour chaque niveau de relation?

+0

http://stackoverflow.com/questions/1744705/oracle-hierarchical-query?rq=1 –

Répondre

2
create table ancestor (name varchar2(200), parent varchar2(200)); 

insert into ancestor values ('john','peter'); 
insert into ancestor values ('peter','ronald'); 
insert into ancestor values ('ronald','george'); 
insert into ancestor values ('george',null); 

select name,parent,relation_level from 
(

SELECT CONNECT_BY_ROOT name name, parent,level relation_level 
FROM ancestor 
CONNECT BY name = PRIOR parent 
    START WITH name IN (SELECT name FROM ancestor) 
) 
where parent is not null; 

SQLFIDDLE

+0

Merci beaucoup, c'est exactement ce que je cherchais! N'a pas compris la fonction connect_by_root, maintenant cela fonctionne parfaitement! –

3

Ou vous pouvez supprimer le start with clause

SELECT name, ancestor AS parent, l 
FROM 
(
    SELECT name, parent, LEVEL-1 l, connect_by_root name ancestor 
    FROM T_Person 
CONNECT BY PRIOR name = parent 
) t 
WHERE t.ancestor <> t.name 

Here is a sqlfiddle demo

+0

@jorg: A.B.Cade solution est plus optimisée que moi, je pense que vous devriez aller avec ce seul –

+0

ce commentaire n'ajoute pas beaucoup mais - putain "vous rock!" Merci beaucoup. –

Questions connexes