【发布时间】:2016-05-22 14:07:36
【问题描述】:
我的 PostgreSQL 数据库中有一个 edges 表,它表示 有向 图的边,有两列:node_from 和 node_to(值是节点的 id)。
给定一个节点 (initial_node),我希望能够以无向方式遍历整个图。
我的意思是,例如下图:
(a->b)
(c->b)
(c->d)
如果 initial_node 是 a、b、c 或 d,无论如何,我都会得到 [a, b, c, d]。
我使用了以下 SQL 查询(基于 http://www.postgresql.org/docs/8.4/static/queries-with.html ):
WITH RECURSIVE search_graph(uniq, depth, path, cycle) AS (
SELECT
CASE WHEN g.node_from = 'initial_node' THEN g.node_to ELSE g.node_from END,
1,
CASE WHEN g.node_from = 'initial_node' THEN ARRAY[g.node_from] ELSE ARRAY[g.node_to] END,
false
FROM edges g
WHERE 'initial_node' in (node_from, node_to)
UNION ALL
SELECT
CASE WHEN g.node_from = sg.uniq THEN g.node_to ELSE g.node_from END,
sg.depth + 1,
CASE WHEN g.node_from = sg.uniq THEN path || g.node_from ELSE path || g.node_to END,
g.node_to = ANY(path) OR g.node_from = ANY(path)
FROM edges g, search_graph sg
WHERE sg.uniq IN (g.node_from, g.node_to) AND NOT cycle
)
SELECT * FROM search_graph
它工作得很好......直到我有一个有 12 个节点的案例,这些节点在所有方向上都连接在一起(对于每一对我都有 (a->b) 和 (b->a)),这使得查询无限循环。 (将 UNION ALL 更改为 UNION 并不能消除循环。)
有没有人对处理这个问题有任何建议?
干杯,
安托万。
【问题讨论】:
标签: postgresql recursion graph traversal