我正在尝试使用 PostgreSQL 中的递归子句从特定节点遍历节点。(顺便说一句,我是 Postgresql 的新手)这是我的 db 表的一个简单版本:
table: nodes
|--------------|------------------|
| id | node_name |
|--------------|------------------|
| 1 | A |
|--------------|------------------|
| 2 | B |
|--------------|------------------|
| 3 | C |
|--------------|------------------|
| 4 | D |
|--------------|------------------|
| 5 | E |
table: links
|--------------|---------------------|-----------------|
| id | id_from | id_to |
|--------------|---------------------|-----------------|
| 1 | 1 | 2 |
|--------------|---------------------|-----------------|
| 2 | 1 | 3 |
|--------------|---------------------|-----------------|
| 3 | 2 | 4 |
|--------------|---------------------|-----------------|
| 4 | 3 | 4 |
|--------------|---------------------|-----------------|
| 5 | 4 | 5 |
所以,这只是这个简单的直接图。(所有边缘从左到右)
B
/ \
A D - E
\ /
C
在这种情况下,从 A 开始获取所有可以访问的顶点的有效方法是什么?
我试过的:
在 SQL (PostgreSQL) 中的简单图搜索算法中找到的 dfs 解决方案
with recursive graph(node1, node2, path) as
(
select id_from, id_to, ARRAY[id_from] from links
where id_from = 1
union all
select nxt.id_from, nxt.id_to,array_append(prv.path, nxt.id_from)
from links nxt, graph prv
where nxt.id_from = prv.node2
and nxt.id_from != ALL(prv.path)
)
select * from graph
它给了我几乎所有的路径。但它访问了 D 顶点两次。(执行 D -> E 逻辑两次)我想忽略访问的顶点以提高效率。
那么,我怎样才能做到这一点?提前致谢!
事情没那么简单。在单个查询中,所有递归路径都是完全独立的。因此,每条路径都不知道兄弟路径上发生了什么。它不知道某个节点已经被兄弟节点访问过。
因为 SQL 查询不支持某种全局变量,所以不可能在递归路径之间以这种方式共享此类信息。
我建议编写一个函数,您可以在其中使用 plsql 语法,以更“常见的编程”方式解决问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句