如何使用递归查询跟踪以前的 ID?

How do I trace former ids using a recursive query?

我有 table 提供者信息(提供者),其中包含列 reporting_unit 和 predesessor。前任是 null 或包含该行用来表示的 reporting_unit。我需要 查找任何提供商的当前 reporting_unit 是什么。我的意思是对于任何有前任的 reporting_unit,reporting_unit 是前任的 current_reporting_unit。

我在努力 使用递归 CTE 来完成此操作,因为有时 有多个链接。

table 看起来像这样:

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
;

但这并没有给我想要的结果。我在这个查询上尝试了多种变体,但它们似乎都以无限循环告终。如何

您应该以相反的顺序查找关系。添加 depth 列以查找最深的 link:

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 行和 select 最深的 links:

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)