sql - 使用 SQL 最小化图形
问题描述
假设我们有一个定义如下的有向图:
node | neighbor
-----------------
1 | 2
1 | 3
2 | 4
2 | 3
3 | 4
上表定义了两个节点之间的唯一边,(1,2)
例如一对表示该节点1
和2
通过边连接,这是图表的图。
我还有一个图的传递闭包表,该表包含图的所有可能路径(例如:(1,3)
存在两次,因为它可以直接或通过路径到达1=>2=>3
),这里是表:
node | neighbor
-----------------
1 | 2
1 | 3
2 | 4
2 | 3
3 | 4
1 | 3
1 | 4
1 | 4
2 | 4
从这两个表中,我想返回一个最小化的图而不失去任何可达性,一个想法是只返回不依赖于两个表的边,这是一个例子:
(1,2)
在第一个表(2,3)
中,在第二个表中,并且因此(1,3)
可以从第一个表中删除,因为您可以通过节点到达节点3
,
输出表应如下所示:1
2
node | neighbor
-----------------
1 | 2
2 | 3
3 | 4
我怎样才能编写一个 SQL 查询来做到这一点?
解决方案
这是一种方法:
with recursive cte as (
select node, neighbor, 1 is_initial from graph
union all
select c.node, g.neighbor, 0
from cte c
inner join graph g on g.node = c.neighbor
)
select node, neighbor
from graph g
where not exists (
select 1
from cte c
where c.node = g.node and c.neighbor = g.neighbor and c.is_initial = 0
)
order by node, neighbor
这仅使用第一个表(我称之为graph
)。我们首先使用递归查询生成所有可能的路径。这与您的闭包表非常相似,但有一个额外的列 ,is_initial
表示路径是来自原始表,还是在进一步迭代期间生成。
然后,剩下要做的就是过滤图形以删除匹配“非初始”路径的元组。
节点 | 邻居 ---: | --------: 1 | 2 2 | 3 3 | 4
推荐阅读
- mysql - 在mysql中格式化日期
- sharepoint-online - Sharepoint Online 插件抛出“无效的发行者或签名”
- c# - 向下键上的 UWP 文本框光标功能
- java - 为什么在 Intellij 中突出显示 setName 和 getName 函数?
- json - 复杂 Json 结构的 Hive 创建表查询
- cjson - 我无法通过有效的方式使用 cjson 来解析巨大的 json 文件,但是 cjson 库很好实现
- json - 是否有必要在返回的响应中包含以令牌编码的数据?
- mysql - 查看和设置运算符 MySQL
- javascript - 如何在JS中获取匹配字符串的索引
- javascript - 如何基于多个属性组合单个对象数组