Frage

Ich habe eine hierarchische Abfrage eine Berichtsstruktur zu verfolgen. Diese fast funktioniert, mit der Ausnahme, dass es nicht den Hinweis auf die sehr Top-Level-Knoten, wahrscheinlich, weil die Top-Level-Leute „Bericht“, um sich selbst.

Die Abfrage ist:

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

Dies erzeugt:

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

Ich bin nicht immer eine Ebene 4, da es aussehen würde:

4      17839 17839

Ohne Daten zu ändern, ist es eine Möglichkeit, meine Anfrage zu verändern, so dass alle vier Ebenen zurückgegeben werden? Das Ziel ist es, die empids zu bekommen, so dass ich einen Scheck über

tun

id in (hierarchical subquery)

übrigens, wenn ich die NOCYCLE aus der Abfrage entfernen bekomme ich einen Fehler.

War es hilfreich?

Lösung

Chris

Sie erhalten nur 3 Zeilen, weil Ihre Top-Level-Zeile nicht die Art und Weise festgelegt wird, soll hierarchische Abfragen zu verarbeiten. Typischerweise ist die Top-Level-Zeile oder Präsident KING in Oracle bekannter Tabelle EMP, hat keinen Manager. In Ihrem Fall sollten Sie nicht setzen die parentid von 17.389-17.389 selbst, sondern auf NULL. Entweder die Tabelle entsprechend aktualisieren, oder einen Blick auf diese Situation zu empfangen verwenden.

Ein Beispiel:

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.

Dieser Teil der EMP-Tabelle hat vier Ebenen mit seiner obersten Ebene Reihe (7839) auf sich. Das gleiche wie Ihre empid 17839. Und dies führt zu nur drei Reihen Kriterien:

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.

Verwenden Sie entweder eine (Inline), die eine Mgr / parentid Spalte setzen für die oberste Ebene auf null:

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.

oder fixieren Sie Ihre Daten mit einer UPDATE-Anweisung:

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.

Und Sie können auch das NOCYCLE Stichwort auslassen, nachdem Sie Befestigung erfolgt ist.

Viele Grüße, Rob.

Andere Tipps

Sie müssen die Hierarchie umgekehrt zu tun, von der Wurzel zu den Blättern.

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

Sie müssen nicht Ihre Struktur ändern.

nur verwenden Sie die folgende Abfrage

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

Van Heddegem Roeland Antwort nicht für mich arbeiten, hatte ich schon versucht, aber ich habe es geschafft, ohne eine Inline-Ansicht zu tun, in der connect-Klausel, durch Zugabe von: -

and prior empid <> parentid

Der folgende Beitrag erklärt, warum das funktioniert - wenn Sie Ihren Kopf um es zu bekommen! Obwohl klingt es logisch Sinn machen, wenn Sie 'bekommen es. (Es ist mit der Reihenfolge der Auswertung von jeder Seite des Operators <> zu tun.)

Oracle: Verbinden von Loop in Benutzerdaten

Die Inline-Ansicht funktioniert aber ohne Forschung auf bestimmte Datenmenge, ich weiß nicht, welche Auswirkungen eine Inline-Ansicht auf dem Abfragepfad haben könnte. die zusätzliche Klausel Hinzufügen wird wahrscheinlich den ‚richtigen‘ Weg, um es in den meisten Fällen zu tun, IMHO.

scheint, wie Sie einen Zyklus in Daten haben. Ohne „NOCYCLE“ wird es nicht sofort funktionieren. Wenn Sie wissen, dass alle Ihre Daten maximale Verschachtelungstiefe 4 hat, dann könnten Sie Bedingung „und Ebene <= 4“ und entfernen NOCYCLE hinzufügen. Sollte funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top