2012-11-09 2 views
1

J'ai besoin d'obtenir les enfants d'un nœud donné, avec un champ qui appartient à leur plus haut ancêtre. Je sais comment obtenir les deux, individuellement, et je pourrais probablement comprendre comment combiner les deux plus tard; mais je préférerais tout faire en une seule requête.Oracle - obtenir les enfants et les grands-parents

En supposant que ma table comprend le champs id, item_id, le code et le nom, et qu'un item_id de 0 est un nœud racine, et que mon arbre ressemble à:

id item_id code  name level 
------------------------------------ 
1 0     Root 1 
2 1  my_value Child1 2 
3 2     Child2 3 

je peux obtenir les noeuds I besoin en utilisant:

select id, item_id, code, name, level from my_table 
start with code like '%my_value%' 
connect by prior id = item_id 

qui retourne:

id item_id code  name level 
------------------------------------- 
2 1  my_value Child1 2 
3 2     Child2 3 

Je voudrais aussi obtenir le champ nom du haut ancêtre (s) de ces nœuds. Je peux obtenir ces noeuds en utilisant:

select id, item_id, code, name, level from my_table 
where level = (
    select max(level) as max_level from my_table 
    start with code like '%my_value%' 
    connect by prior item_id = id 
) 
start with code like '%my_value%' 
connect by prior item_id = id 

qui retourne:

id item_id code  name level 
------------------------------------- 
1 0     Root 1 

Je voudrais ajouter le champ de nom renvoyé de la requête ci-dessus comme un champ supplémentaire ajouté aux deux noeuds de retour de la première requête, c'est-à-dire

id item_id code  name root_name level 
------------------------------------------------ 
2 1  my_value Child1 Root  2 
3 2     Child2 Root  3 

J'espère que c'est clair. Aucune suggestion?

Répondre

2

peut-être commencer à partir de la racine, puis filtrer ensuite pour limiter à commencer avec des codes comme my_value?

SQL> select id, item_id, code, name, lvl, root_name 
    2 from (select id, item_id, code, name, level lvl, sys_connect_by_path(code, '|') c, 
    3    connect_by_root name as root_name 
    4    from my_table 
    5   start with item_id = 0 
    6   connect by prior id = item_id) 
    7 where c like '%my_value%'; 

     ID ITEM_ID CODE     NAME    LVL ROOT_NAME 
---------- ---------- -------------------- ---------- ---------- ---------- 
     2   1 my_value    Child1    2 Root 
     3   2      Child2    3 Root 
+0

C'est absolument parfait, merci! Il est temps de lire sur sys_connect_by_path et connect_by_root! – earachefl

Questions connexes