2014-10-09 64 views
4

我在PostgreSQL數據庫的表中包含部分地址以樹的形式,看起來像這樣:如何連接字段值與postgresql中的遞歸查詢?

Id | Name   | ParentId 
1 | London  | 0 
2 | Hallam Street| 1 
3 | Bld 26  | 2 
4 | Office 5  | 3 

我想作一個查詢返回的地址,從所有祖先的名字連接在一起。我需要的結果表是這樣的:

Id | Address 
1 | London 
2 | London, Hallam Street 
3 | London, Hallam Street, Bld 26 
4 | London, Hallam Street, Bld 26, Office 5 

我想我必須使用WITH RECURSIVE查詢,但所有的例子我發現使用WHERE子句,所以我必須把WHERE name='Office 5'只得到結果對於那個特定的行。但我需要一個連接地址爲我的初始表的每一行。如何才能做到這一點?

回答

4

遞歸查詢的訣竅是您需要指定種子查詢。這是確定您的根節點的查詢,或者是您正在構建的樹下降或上升的起點。

WHERE子句存在的原因是要建立種子ID=1Name=Bld 26。如果你希望每一條記錄都有樹的上升或下降(取決於你在聯合選擇中指定的內容),那麼你應該放棄WHERE語句,以便記錄所有記錄。

雖然,您給的例子...您可能想要在種子中以WHERE ID=1開頭,寫出孩子ID和父母ID。然後在Union'd SELECT中,將您派生的遞歸表與您從中選擇的表連接起來,並將Derived Recursive表的Child連接到您的表的父項。

喜歡的東西:

WITH RECURSIVE my_tree AS (
    -- Seed 

    SELECT 
     ID as Child, 
     ParentID as Parent, 
     Name, 
     Name as Address 
    FROM <table> 
    WHERE <table>.ID = 1 


    UNION 

    -- Recursive Term 
    SELECT 
    table.id as Child, 
    table.parent_id as Parent, 
    table.name, 
    t.address || ', ' || table.name as Address 

    FROM my_tree as t 
    INNER JOIN <table> table ON 
     t.Child = table.Parent_Id 
) 
SELECT Child, Address from my_tree; 

我以前沒使用PostgreSQL數據庫,所以你可能要大驚小怪一點的語法,但我認爲這是針對RDBMS相當準確。

+0

「種子」查詢周圍的括號毫無用處(並且在我個人看來令人困惑)。此外,字符串文字需要用SQL中的單引號('','')括起來,而不是雙引號(雙引號用於標識符) – 2014-10-10 12:48:31

+0

謝謝,@a_horse_with_no_name!我認爲種子周圍的種子很奇怪。我從一個我在網上找到的postgresql示例開始工作,並認爲它可能關心。我使用Teradata,看起來語法幾乎完全相同,除非它在每個字段未在WITH RECURSIVE子句中明確聲明的情況下都會引起混淆。 – JNevill 2014-10-10 12:53:07

+0

這似乎是一個常見的誤解,一個聯合(或聯合所有)查詢需要括號,所以我並不感到驚訝,你發現網上某處。我不知道從哪裏來,儘管 – 2014-10-10 12:55:17