2016-07-22 6 views
0

Ich habe eine hierarchische SQL-Abfrage (mit Oracle) kämpfen. Angenommen, ich habe eine Tabelle mit Widgets mit eindeutigen IDs. Ein Widget kann nur einmal kopiert werden, und wir verfolgen die Eltern-ID aus dem neuen Widget. Zum Beispiel wird können sagen Widget 100 kopiert und werden Widget 101, dann 103, dann 105.SQL hierarchische Abfrage: finden Sie die vollständige Struktur mit einer ID von einem Eltern-Kind (Oracle)

id parent_id 
100 
101 100 
102 
103 101 
104 
105 103 

CREATE TABLE WIDGETS (ID NUMBER NOT NULL, PARENT_ID NUMBER); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (100, null); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (101, 100); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (102, null); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (103, 101); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (104, null); 
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (105, 103); 

(102 und 104 sind nur Dummy-Daten)

Ich versuche, eine Abfrage, die Displays zu machen Der vollständige Verlauf eines Widgets unter Verwendung einer der IDs in der Beziehung.

Also, wenn ich der Abfrage eine ID von '103' (oder '100' ... 'oder' 105') geben, würde ich die Abfrage erwarten, so etwas zurück:

id parent_id  
100 
101 100 
103 101 
105 103 

I habe versucht, CONNECT BY PRIOR zu verwenden, aber ich würde den Start per ID beginnen müssen. Zum Beispiel kann ich den vollen Baum gibt die Abfrage die Herkunft ID angezeigt:

select parent_id as from_id, id as to_id 
from WIDGETS 
start with id = 100 
CONNECT BY PRIOR id = parent_id; 

from_id to_id 
null  100 
100  101 
101  103 
103  105 

Aber was, wenn ich weiß nicht unbedingt den Anfang mit id? Ist es möglich, die Ursprungs-ID zu finden und dann den vollständigen Baum von dort zu bekommen?

Antwort

1

Berechnen Sie den Start, indem Sie den Baum rückwärts durchlaufen, bis Sie ein Blatt treffen. SELECT parent_id AS from_id, ID AS to_id FROM WIDGETS START WITH ID = (SELECT ID FROM WIDGETS WHERE CONNECT_BY_ISLEAF=1 START WITH ID = 105 CONNECT BY ID = PRIOR parent_id ) CONNECT BY PRIOR ID = parent_id;

+1

Wenn Sie 'änderte sich mit ID START =' auf 'MIT ID START IN' es sogar mit dem Hinzufügen des Paares (101, 104) zu bewältigen wäre. – Unoembre

+0

Genau das habe ich gesucht, danke. – a3uge

-1

@Eingabe unten ist die Eingabe-ID, die Sie an die gespeicherte Prozedur übergeben. Versuchen Sie dies, hoffe, es hilft:

DECLARE @Parent int; 

WHILE (Select @Parent = PARENT_ID From Widgets Where ID = @Input) Is NOT NULL 
BEGIN 
Set @Input = @Parent 
END 
Set @Parent = @Input 

declare @Hierarchy table(Member int) 
INSERT INTO @Hierarchy(Member) Values (@Parent) 
WHILE (Select @Input = ID From Widgets Where PARENT_ID = @Parent) Is NOT NULL 
BEGIN 
SET @Parent = @Input 
INSERT INTO @Hierarchy(Member) Values (@Parent) 
END 

Select * From @Hierarchy 
+0

Warum gespeicherte Prozeduren für eine triviale hierarchische Abfrage verwenden? Definitive Verdienst! – mathguy

+0

Ich dachte, er versucht, ein gespeichertes Proc zu erstellen. –

+0

Warum hast du das gedacht? Es gibt absolut nichts in der ursprünglichen Post, um darauf hinzuweisen, dass das OP nach einer Stored-Procedure-Lösung suchte. – mathguy

Verwandte Themen