2016-04-08 18 views
1

Tabelle "Links" enthält zwei Spalten: PARENT_CODE, CHILD_CODEOptimieren Hierarchie Abfrage in Oracle

PARENT_CODE | CHILD_CODE 
------------|------------ 
A1   | B1 
A1   | B2 
B1   | C1 
B1   | C2 
B2   | C3 
B3   | C3 
C3   | D1 

Diese Tabelle schließlich verwendet folgende Diagramm zu bilden:

node structure

Meine Frage wird sein, wie man eine optimierte Hierarchieabfrage in Oracle schreibt, um den gesamten Graphen verbunden zu bekommen, und der Eingabeparameter wird irgendein Knoten sein.

Um die Eingabe/Ausgabe veranschaulichen, diese SQL vereinfacht: SELECT PARENT_CODE, CHILD_CODE FROM {HIERARCHY QUERY} wobei node = {ANY NODE}

+0

Ich weiß, es gibt eine hierarchische Abfrage in Oracle, aber es wird nicht alle verbundenen Knoten geben. – Adelave

+0

Sie können connect by verwenden, um dies zu tun. Wählen Sie parent_code, child_code, level von den Links, die nach vorherigem child_code = parent_code verbunden sind. Es macht einen linken Baumspaziergang und stellt auch eine Pseudospalte mit der Ebene (Tiefe) bereit, die es gerade bewertet. Damit dies mit jeder Leistung funktioniert, müssen beide Spalten indiziert werden (unabhängig). WHOOPS - wenn B3 kein Kind von A1 ist, bricht dies. –

Antwort

0

Die Abfrage unten mit zeigen Sie alle Verbindungen. Die Idee ist, dass ich zuerst zwei Arten Verbindung zwischen Knoten erstelle. Mit ihr können wir eine rekursive Abfrage durchführen, die unsere Ergebnisse zurückgibt. Das letzte Ding ist das Dekodieren, das zurückbringt, wer das reale Elternteil ist und wer Kind, das auf dir basiert (0 - bedeutet ursprüngliche Richtung, 1 - bedeutet umgekehrte Richtung).

with linkT (parent_code, child_code) as 
(select 'A1','B1' from dual union all 
select 'A1','B2' from dual union all 
select 'B1','C1' from dual union all 
select 'B1','C2' from dual union all 
select 'B2','C3' from dual union all 
select 'B3','C3' from dual union all 
select 'C3','D1' from dual union all 
select 'E1','F1' from dual), 
T1 as (
select parent_code, child_code, 0 Dir from linkT 
union all 
select child_code, parent_code, 1 Dir from linkT) 
select distinct 
     decode(dir, 0, parent_code, child_code) as Parent_code, 
     decode(dir, 0, child_code, parent_code) as Child_Code 
from (
select parent_code, child_code, dir 
from T1 x 
start with x.child_code='A1' 
connect by nocycle prior x.parent_code=x.child_code) 
order by 1,2 
+0

Das ist genial und genau das, was ich brauchte! – Adelave