postgresql 递归选择节点祖先

vlf7wbxs  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(120)

假设我有下面的树:

存储数据的表相应如下所示:
| 节点标识|父标识|
| - -|- -|
| A级|零值|
| B| A级|
| C语言|A级|
| D级|B|
我想选择树中每个节点的所有祖先节点。
根节点没有祖先,所以不会显示。
我想要的例子-
| 节点标识|祖先标识|
| - -|- -|
| B| A级|
| C语言|A级|
| D级|B|
| D级|A级|
很高兴得到任何帮助:)
我正在使用pgsql。

h6my8fg2

h6my8fg21#

您需要递归查询:

WITH RECURSIVE cte AS (
SELECT node_id, parent_id AS ancestor_id
  FROM your_table
 WHERE parent_id is not null
UNION ALL
SELECT children.node_id, parent.parent_id
  FROM cte AS chidren
 INNER JOIN your_table AS parent
    ON parent.node_id = children.parent_id
)
SELECT *
  FROM cte ;

如果在node_id =〉paren_id树中有循环,这个查询可能不会停止。为了避免递归查询中出现无限循环,必须添加一个测试:

WITH RECURSIVE cte AS (
SELECT node_id, parent_id AS ancestor_id, array[node_id, parent_id] AS check
  FROM your_table
 WHERE parent_id is not null
UNION ALL
SELECT children.node_id, parent.parent_id, children.check || parent.parent_id
  FROM cte AS chidren
 INNER JOIN your_table AS parent
    ON parent.node_id = children.parent_id
 WHERE NOT children.check @> array[parent.parent_id]  -- this condition will avoid infinite loops
)
SELECT node_id, ancestor_id
  FROM cte ;

相关问题