递归 CTE 中存在条件

问题描述 投票:0回答:1

我尝试使用“RECURSIVE CTE 中的 EXISTS 条件”来停止递归,但出现 SQL 错误 [42P19]。 PostgreSQL 版本 13.2。 有没有办法绕过这个限制?

下面的 Sql 查询创建一个具有节点父关系的表。我需要构建从任何基本节点到任何嵌套节点的相对路径。 例子。给定输入参数 base_id(1) 和 rel_id(4),结果应为“1/2/4”。 我知道查询会显示多个路径,但故意简化了查询以使其更易于理解。


DROP TABLE IF EXISTS nodes;

CREATE TABLE nodes (
    id INT4
    , parent_id INT4
);

INSERT INTO nodes (
    id, parent_id
) VALUES (
    1, NULL
), (
    2, 1
), (
    3, 1
), (
    4, 2
), (
    5, 4
);

-- get rel path by base id 1 to rel id 4
WITH RECURSIVE r AS (
    SELECT n.id, n.parent_id, '' rel_path
    FROM nodes n
    WHERE n.id = 1 -- base
    UNION ALL 
    SELECT n.id, n.parent_id, CONCAT(rel_path, ' / ', n.id) rel_path
    FROM r
    JOIN nodes n ON n.parent_id = r.id
    WHERE NOT EXISTS (
        SELECT *
        FROM r r_sub
        WHERE r_sub.id = 4 -- rel
    )
)
SELECT rel_path
FROM r

沙箱相关 https://extendsclass.com/postgresql/1a1bc61

我尝试将查询的第二部分括在括号中,但没有帮助。

sql postgresql plpgsql common-table-expression recursive-query
1个回答
0
投票

您的查询中已经有

r
,过滤器可以简化为
!=
。它不会停止替代路径,但您还可以在最外面的选择中进行过滤。

WITH RECURSIVE r AS (
    SELECT n.id, n.parent_id, n.id::text rel_path -- here you need to initiate rel_path
    FROM nodes n
    WHERE n.id = 1 -- base
    UNION ALL 
    SELECT n.id, n.parent_id, CONCAT(rel_path, ' / ', n.id) rel_path
    FROM r
    JOIN nodes n ON n.parent_id = r.id
    WHERE r.id != 4
)
SELECT rel_path
FROM r
where r.id = 4

结果:

1 / 2 / 4

© www.soinside.com 2019 - 2024. All rights reserved.