2017-09-28 92 views
1

我使用Oracle的遞歸方法時,我無法獲取所需的結果我的查詢:遞歸SQL檢索各級

ID1  ID2 
1  2 
1  3 
4  2 
4  3 
4  5 

查詢:

select sys_connect_by_path(id2,' -> ') 
FROM Foo 
    START WITH id1 = 1 
    CONNECT BY PRIOR id1 = id2 
ORDER BY 1; 

只輸出水平1層次(2,3)。我想要它檢測樹(1->(2,3)→4→5),以便選擇不同的產生(2,3,5)。謝謝。

+0

?你的樹只有最高等級1。在你的查詢中,你從ID1 = 1開始,在你的數據中沒有辦法從那裏到ID2 = 5。您的數據需要一行ID1 = 2,ID2 = 5。或者ID1 = 1,ID2 = 4。或者你可以擺脫「用id1 = 1開始」來顯示你的整個樹 - 但仍然只有1級,所以'connect by'什麼都不做。 – kfinity

+0

請發佈查詢的預期輸出。你也可以在(1,4)中使用'START WITH id1',即從沒有父節點的所有ID1開始 - 這將在選擇表中的所有行時結束。 –

+0

'select distinct id2' does does yield the records 2,3,5。問題是什麼? –

回答

0

如果您使用的是Oracle 11.2或更高版本,則使用Oracle的CONNECT BY聲明優先使用CTE(公用表表達式)。

WITH 
    aset -- Create pseudo table with ID2 as ID1 and vice versa 
    AS 
     (SELECT id1, id2 
      FROM (SELECT id1, id2 
        FROM foo 
       UNION 
       SELECT id2, id1 
        FROM foo) 
      WHERE id1 < id2), 
    bset (id1, id2) -- Extract hierarchy from pseudo table 
    AS 
     (SELECT id1, id2 
      FROM aset 
      WHERE id1 = 1 
     UNION ALL 
     SELECT aset.id1, aset.id2 
      FROM bset INNER JOIN aset ON bset.id2 = aset.id1 
      WHERE bset.id1 <> aset.id2) 
    SELECT DISTINCT bset.id2 -- Only keep values that were originally ID2 
    FROM bset INNER JOIN foo ON bset.id2 = foo.id2 
ORDER BY id2; 

下面是使用CONNECT你能不能約你期望看到更清晰的同樣的事情BY

WITH 
    aset 
    -- Create pseudo table with ID2 as ID1 and vice versa 
    AS 
     (SELECT id1, id2 
      FROM (SELECT id1, id2 
        FROM foo 
       UNION 
       SELECT id2, id1 
        FROM foo) 
      WHERE id1 < id2), 
    bset 
    -- Extract hierarchy from pseudo table 
    AS 
     ( SELECT id2 
       FROM aset 
     START WITH id1 = 1 
     CONNECT BY PRIOR id2 = id1) 
    SELECT DISTINCT bset.id2 
    -- Only keep values that were originally ID2 
    FROM bset INNER JOIN foo ON bset.id2 = foo.id2 
ORDER BY id2 
+0

非常感謝Brian。任何建議有'whiere id1 = 2'不輸出5?目前它將由於在一張表中反向UNION。再次感謝! –

+0

另外,虛擬表'aset'(反向聯合)是一種已知的模式/概念,我可以在某處閱讀嗎?感謝Brian。 –

+0

我將這個例程寫入了您提供的數據。我相信你的數據是不正確的,但我仍然適應它來得到你想要的結果。正如@ kfinity所述,您應該使用(id1,id2)(2,4)(3,4)的附加記錄來反映從2到4以及3到4的連接。根據您提供的數據獲得的期望結果具有ID2值通過ID2中的其他值鏈接回ID1,因此我的反向聯合。這不是分層表的正常關係。 –