2013-12-15 56 views
1

這是我第一次嘗試遞歸SQL查詢向上遍歷N個父子關係,我不知道從哪裏開始。任何幫助,將不勝感激。遞歸SELECT查詢返回任意深度的速率?

情景是我有兩個表 - raterate_plan。費率屬於應用於用戶的費率計劃。

CREATE TERM rate_plan (
    id     integer PRIMARY KEY NOT NULL 
         DEFAULT nextval('rate_plan_id'), 

    descr    varchar(64) NOT NULL, 

    parent_rate_plan_id integer NOT NULL REFERENCES rate_plan(id) 
); 

CREATE TABLE rate (
    id    integer PRIMARY KEY NOT NULL 
        DEFAULT nextval('rate_id'), 

    prefix   varchar(24) NOT NULL, 

    rate_plan_id  integer NOT NULL 
        REFERENCES rate_plan(id) 
); 

一個典型的查詢來獲取率:

SELECT * FROM rate 
    WHERE (
     rate_plan_id = ${user rate plan ID} 
     AND prefix = ${prefix} 
    ) 
    ORDER BY LENGTH(prefix) ASC; 

我想什麼是返回特定的多數(LENGTH() -iest前綴)率,但不限於${user rate plan ID},而是從rate_plan.parent_rate_plan_id層次結構中的任何費率計劃的附屬機構中選擇利率。當rate_plan.parent_rate_plan_id = NULL時,遞歸應該是最低的。

我只是做一個JOIN,但我需要容納N個父子關係,而不僅僅是兩個。

這是在PostgreSQL 9.x.我試過WITH RECURSIVEUNION ALL,每SELECT加入rate_planrate,並試圖按父母過濾,但由於對這些構造的工作原理認識不足而無法獲得。

+0

我並不完全明白你想要做什麼。但是在CTE的文檔中,有一個查詢圖的示例,它使用數組構建父節點的路徑。對你的樹做同樣的事情:你希望的查詢應該是(希望)顯而易見的,例如,每個節點的父母都將您的前綴包含在節點中,或者您正在尋找的任何節點。 –

+0

你能準備一些樣本數據(一些插入)並將其輸入到這個sqlfiddle:http://www.sqlfiddle.com/#!15/89073/1?然後附加一個鏈接到SQLFiddne,並根據這些數據解釋你的需求並展示預期的結果。 – krokodilko

+0

[Postgres主要版本](http://www.postgresql.org/support/versioning/)包括點後面的第一個數字。目前的版本是* 9.3 *。 –

回答

2

這可能是你在找什麼,根據你的描述:

的最特定(LENGTH() -iest前綴)率,但不限於 ${user rate plan ID},而是從那些採摘率附屬

WITH RECURSIVE cte AS (
    SELECT id, parent_rate_plan_id 
    FROM rate_plan 
    WHERE id = ${user rate plan ID} 

    UNION ALL 
    SELECT rp.id, rp.parent_rate_plan_id 
    FROM cte 
    JOIN rate_plan rp ON rp.id = cte.parent_rate_plan_id 
    ) 
SELECT * 
FROM cte 
JOIN rate r ON r.rate_plan_id = cte.id 
ODER BY length(prefix) DESC 
LIMIT 1; 

遞歸如一旦達到頂部節點(parent_rate_plan_id IS NULL)自動停止。

在收集完所有計劃後,加入rate會更有效。

The manual on (recursive) CTEs.

+0

這似乎是正確的想法;然而,Postgres不會讓我把它當作「WITH cte」來運行,抱怨它是自我指涉的。但是當我使用WITH RECURSIVE運行它時,它似乎無限遞歸。 –

+0

我糾正了;我錯誤地實施了你的建議。這確實似乎做到了!謝謝。 –

+0

@AlexBalashov:增加了缺少的'RECURSIVE'子句。 –