Question

J'ai une requête hiérarchique pour suivre une structure hiérarchique. Cela fonctionne presque, sauf que ce n'est pas le nœud de rapports de niveau très haut, probablement parce que les gens de haut niveau « rapport » eux-mêmes.

La requête est:

select
  level,
  empid, 
  parentid
from usertable
connect by nocycle prior parentid= empid
start with empid = 50

produit:

LEVEL  EMPID PARENTID               
------ ----- --------  
1      50    258            
2      258   9555
3      9555  17839

Je ne reçois pas un niveau 4, car il ressemblerait à ceci:

4      17839 17839

Sans modifier les données, est-il un moyen de modifier ma requête afin que tous les 4 niveaux sont retournés? Le but est d'obtenir les empids, donc je peux faire un chèque pour

id in (hierarchical subquery)

BTW, si je retire la nocycle de la requête que je reçois une erreur.

Était-ce utile?

La solution

Chris,

Vous obtenez seulement 3 rangs parce que votre ligne de haut niveau n'est pas réglé comme il se doit pour traiter les requêtes hiérarchiques. En règle générale la ligne de haut niveau, ou KING président dans la table EMP bien connue d'Oracle, n'a pas gestionnaire. Dans votre cas, vous ne devez pas définir la parentid de 17389-17389 lui-même, mais à NULL. Soit mettre à jour le tableau en conséquence, ou en vue d'accueillir cette situation.

Un exemple:

SQL> select empno
  2       , mgr
  3    from emp
  4   where empno in (7876,7788,7566,7839)
  5  /

     EMPNO        MGR
---------- ----------
      7566       7839
      7788       7566
      7839       7839
      7876       7788

4 rijen zijn geselecteerd.

Cette partie de la table EMP a quatre niveaux avec sa ligne de premier niveau (7839) fixé à lui-même. La même chose que votre empid 17839. Et cela conduit à trois lignes à l'aide de votre requête:

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839

3 rijen zijn geselecteerd.

Soit utiliser un (inline) en vue de fixer la colonne mgr / parentid null pour le niveau haut:

SQL>  select level
  2        , empno
  3        , mgr
  4     from ( select empno
  5                 , nullif(mgr,empno) mgr
  6              from emp
  7          )
  8  connect by nocycle prior mgr = empno
  9    start with empno = 7876
 10  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.

Ou fixer vos données avec une instruction UPDATE:

SQL> update emp
  2     set mgr = null
  3   where empno = 7839
  4  /

1 rij is bijgewerkt.

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.

Et vous pouvez laisser le mot-clé NOCYCLE aussi bien, après avoir terminé la fixation.

Cordialement, Rob.

Autres conseils

Vous devez faire la hiérarchie dans l'autre sens, de la racine aux feuilles.

select
  level,
  empid, 
  parentid
from usertable
start with empid = 17839
connect by empid != 17839 and prior empid = parentid

LEVEL                  EMPID                  PARENTID               
---------------------- ---------------------- ---------------------- 
1                      17839                  17839                  
2                      9555                   17839                  
3                      258                    9555                   
4                      50                     258                    

4 rows selected

Vous ne devez pas changer votre structure.

il suffit d'utiliser la requête suivante

select
  level,
  empid,
  parentid
from usertable
connect by prior parentid = empid
       AND parentid <> empid  -- This line prohibits cycling and ALLOWS a row where parentid = empid
start with empid = 50

La réponse de Van Heddegem Roeland ne fonctionne pas pour moi, je l'avais déjà essayé, mais je l'ai réussi à le faire sans une vue en ligne, dans la clause de connexion, en ajoutant: -

and prior empid <> parentid

Le message suivant explique pourquoi cela fonctionne - si vous pouvez obtenir votre tête autour d'elle! Bien qu'il ne fait son sens logique une fois que vous ne l'obtenez « ». (Il est à voir avec l'ordre d'évaluation de chaque côté de l'opérateur <>).

Oracle: Se connecter par boucle dans les données utilisateur

La vue en ligne fonctionne, mais sans la recherche sur votre ensemble de données particulier, je ne sais pas quel impact une vue en ligne pourrait avoir sur le chemin de la requête. L'ajout de la clause supplémentaire est probablement la façon « correcte » de le faire dans la plupart des situations, à mon humble avis.

semble que vous avez un cycle dans les données. Sans « nocycle » ça ne marchera pas tout de suite. Si vous savez que toutes vos données niveau d'imbrication maximum de 4, alors vous pouvez ajouter la condition « et le niveau <= 4 » et retirez nocycle. Si le travail.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top