2015-10-30 59 views
1

我有一個包含列reporting_unit和predesessor的提供者信息(提供者)表。 Predesessor要麼是 null,要麼包含該行用於表示的reporting_unit。我需要 來查找任何提供者的當前reporting_unit。我的意思是,對於任何具有預定義的reporting_unit,reporting_unit是對於predesessor的current_reporting_unit。如何使用遞歸查詢跟蹤以前的id?

我想 使用遞歸CTE來實現這一點,因爲有一些時間 有多個鏈接。

表看起來是這樣的:

CREATE TABLE providers (
    reporting_unit TEXT, 
    predesessor TEXT 
); 

INSERT INTO providers 
VALUES 
    (NULL, NULL), 
    ('ARE88', NULL), 
    ('99BX7', '99BX6'), 
    ('99BX6', '99BX5'), 
    ('99BX5', NULL) 
; 

的結果,我想從那個是:

reporting_unit | current_reporting_unit 
--------------------------------------- 
     '99BX5' | '99BX7' 
     '99BX6' | '99BX7' 

我當前的查詢是:

WITH RECURSIVE current_ru AS (
    SELECT reporting_unit, predesessor 
    FROM providers 
    WHERE predesessor IS NULL 

    UNION ALL 

    SELECT P.reporting_unit, P.predesessor 
    FROM providers P 
     JOIN current_ru CR 
     ON P.reporting_unit = CR.predesessor 
    ) 
SELECT * 
FROM current_ru 
; 

但是,ISN沒有給我我要找的結果。我在這個查詢中嘗試了許多變體,但它們似乎都以無限循環結束。如何

回答

1

你應該找到相反的關係。添加depth列查找最深的鏈接:

with recursive current_ru (reporting_unit, predesessor, depth) as (
    select reporting_unit, predesessor, 1 
    from providers 
    where predesessor is not null 
union 
    select r.reporting_unit, p.predesessor, depth+ 1 
    from providers p 
    join current_ru r 
    on p.reporting_unit = r.predesessor 
    ) 
select * 
from current_ru; 

reporting_unit | predesessor | depth 
----------------+-------------+------- 
99BX7   | 99BX6  |  1 
99BX6   | 99BX5  |  1 
99BX6   |    |  2 
99BX7   | 99BX5  |  2 
99BX7   |    |  3 
(5 rows) 

現在換了兩列,更改其名稱,消除null行,並選擇最深的鏈接:

with recursive current_ru (reporting_unit, predesessor, depth) as (
    select reporting_unit, predesessor, 1 
    from providers 
    where predesessor is not null 
union 
    select r.reporting_unit, p.predesessor, depth+ 1 
    from providers p 
    join current_ru r 
    on p.reporting_unit = r.predesessor 
    ) 
select distinct on(predesessor) 
    predesessor reporting_unit, 
    reporting_unit current_reporting_unit 
from current_ru 
where predesessor is not null 
order by predesessor, depth desc; 

reporting_unit | current_reporting_unit 
----------------+------------------------ 
99BX5   | 99BX7 
99BX6   | 99BX7 
(2 rows)