2016-07-22 47 views
0

我掙扎層次的SQL查詢(使用Oracle)。假設我有帶獨特ID的小部件表格。一個小部件只能被複制一次,並且我們會跟蹤新小部件的父ID。例如,讓我們說插件100被複制和變小部件101,則103,然後105SQL分層查詢:找到完整的樹給出的任何父 - 子(甲骨文)的ID

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和104只是僞數據)

我試圖使一個查詢,顯示一個小部件的完整歷史記錄,使用關係中的任何id。

所以,如果我給查詢的「103」的ID(或「100」 ......或「105」),我預計查詢返回是這樣的:

id parent_id  
100 
101 100 
103 101 
105 103 

我已經嘗試過使用CONNECT BY PRIOR,但是我需要從ID開始才能使用start。例如,我可以顯示完整的樹給查詢的起源ID:

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 

但如果我不一定知道與ID開始?有沒有可能找到起源ID,然後從那裏得到完整的樹?

回答

1

通過向後遍歷樹來計算開始點,直到您點擊樹葉。 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

如果更改了'START WITH ID =''到START WITH ID在'它甚至會用添加對(101,104)應付。 – Unoembre

+0

這正是我正在尋找的,謝謝。 – a3uge

-1

@Input below是您傳遞給存儲過程的輸入ID。試試這個,希望它有助於:

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

爲什麼使用存儲過程進行簡單的分層查詢?明確的德性! – mathguy

+0

我以爲他正在嘗試創建一個存儲過程。 –

+0

你爲什麼這麼想?原帖中絕對沒有建議OP在尋找存儲過程解決方案。 – mathguy