2010-06-30 5 views
4

Par exemple, j'ai ce tableau:Comment créer une sélection simple pour un tableau référentiel?

CREATE TABLE perarea 
    (
    id_area  INT primary key, 
    nombre  VARCHAR2(200), 
    id_areapadre INT references perarea(id_area) 
); 

Au lieu de montrer:

1 IT null 
2 Recursos Humanos null 
3 Contabilidad 2 
4 Legal 2 

Je veux:

1 IT 
2 Recursos Humanos 
3 Contabilidad Recursos Humanos 
4 Legal Recursos Humanos 

Toute aide?

Je ne peux pas pour la vie de moi comprendre comment ce select serait.

Edit:

Cela fonctionne de requêtes SQL, mais ne tire pas le nom, seul l'ID du parent. De l'aide?

select * from PerArea 
connect by id_area = id_areapadre; 
+1

double possible de [requête hiérarchique] (http://stackoverflow.com/questions/1443860/hierarchical-query) – APC

+0

Oracle a sa propre syntaxe pour le traitement des requêtes hiérarchiques, qui n'est pas intuitif: CONNECT BY. La question que j'ai suggérée en tant que doublon devrait vous l'expliquer. – APC

+0

@APC: 11g n'a pas ajouté l'affacturage sous-requête récursif (AKA CTE)? –

Répondre

6

Pour référence, vous pouvez aussi le faire sans extensions hiérarchiques en utilisant un autojointure:

SELECT p1.id_area, p1.name, COALESCE(p2.name, '') 
FROM perarea p1 
    LEFT JOIN perarea p2 ON (p1.id_areapadre = p2.id_area) 
2

On dirait que vous voulez une requête hiérarchique:

select id_area, nombre, sys_connect_by_path(nombre,'/') 
    from perarea 
    start with id_areapadre is null 
    connect by id_areapadre = prior id_area 
    order by id_area 
+1

Cela fonctionne! Mais comment puis-je avoir l'émission "Recursos Humanos" de Parent uniquement, dans "/ Recursos Humanos/Servicios Al Empleado"? Merci! –

+0

Il suffit de remplacer le caractère '/', puis le résultat de soustraire la longueur du nombre actuel –

0

recherchez-vous pour le nom de la racine (CONNECT_BY_ROOT) ou le chemin de sous-chaîne de supprimer le nom "parents"?

SELECT id_area, 
      nombre, 
      PATHLEVEL , 
      SUBSTR(PATHLEVEL,INSTR(PATHLEVEL,'/',-1,2)+1, INSTR(PATHLEVEL,'/',-1)-INSTR(PATHLEVEL,'/',-1,2)-1) PARENTNAME , 
      rootNAME 
    FROM(
    select id_area, nombre, sys_connect_by_path(nombre,'/') PATHLEVEL, 
      CONNECT_BY_ROOT nombre rootNAME, 
     from perarea 
     start with id_areapadre is null 
     connect by id_areapadre = prior id_area 
     order by id_area 
    ); 
3

Ceci est un bon exemple d'une requête hiérarchique. Une solution simple avec CONNECT BY:

SQL> SELECT id_area, nombre, PRIOR (nombre) 
    2 FROM perarea 
    3 CONNECT BY PRIOR (id_area) = id_areapadre 
    4 START WITH id_areapadre IS NULL; 

ID_AREA NOMBRE   PRIOR(NOMBRE) 
-------- ----------------- ----------------- 
     1 IT     
     2 Recursos Humanos 
     3 Contabilidad  Recursos Humanos 
     4 Legal    Recursos Humanos 
Questions connexes