Oracle hierarchische Abfrage: wie Top-Level-Eltern einzubeziehen
-
23-08-2019 - |
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.
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.