处理复杂关系的 SQL 查询

Posted

技术标签:

【中文标题】处理复杂关系的 SQL 查询【英文标题】:SQL query to handle complex relationship 【发布时间】:2011-01-29 16:07:47 【问题描述】:

我有一个场景,我有大量的博客。这些博客都有多个帖子。每个博客帖子都可以链接到另一个博客上的帖子,但他们应该永远从该博客链接回链接博客。

澄清一下:

站点 A 链接到站点 B(并且可以链接到其他站点) 站点 B 然后无法链接到站点 A(但可以链接到其他站点)

每次发布​​帖子时,我都会存储帖子的 ID 和它链接到的网站的 ID。重要的是要记住,一旦单个帖子链接到另一个网站上的任何帖子,而其他网站无法从任何地方链接回来,而不仅仅是它链接到的帖子。

站点 A 可以根据需要多次链接到站点 B,并且每个帖子可以链接到多个其他帖子。一个示例场景可能是:

站点 A 链接到站点 B 站点 C 链接到站点 B 站点 D 链接到站点 A

在上述数据中:

站点 A 可以链接到站点 C(或再次链接到站点 B) 站点 B 可以链接到站点 D 站点 C 可以链接到站点 A 或站点 D(或再次链接到站点 B) 站点 D 可以链接到站点 B 或站点 C(或再次链接到站点 A)

这里是一些测试数据的链接和所需的 2 个表的转储: http://pastie.org/1506715

我认为我需要一个交叉连接来获得所有可能的链接组合,然后考虑现有关系以防止网站反向链接。到目前为止我的查询是:

SELECT 
t1.* , t2.* FROM test_posts t1, test_posts as t2
WHERE
t1.post_id != t2.post_id
ORDER BY
t1.post_id, t2.post_id;

这为我提供了帖子之间所有可能的关系。我正在努力解决的是如何排除与上述规则相矛盾的关系。之前的关系记录在 test_smartlinks_to_websites 表中,post_id 属于“始发”网站,website_id 属于“目的地”网站(请记住,网站之间的关系实际上是单向的,而不是帖子)。

我尝试过使用 NOT EXISTS 子查询,但我不确定确切的子句(或者这是否是正确的方法)。

【问题讨论】:

所以这是一个完全等级的帖子???即:A 链接到 B,B 可以链接到 C,C 到 D,所以即使 C 和 D 没有明确链接到 A,A 是否可以直接链接到 C 和/或 D,即使它们在 B 下?此外,在此示例中,B 也不允许链接到 D,或者它是否可以链接,因为它不是直接链接的? 这不是一个层次结构,它有点像一个链接网络,但没有一个网站应该喜欢回来,一切都应该是单向的。 (我正在与 BrynJ 合作) 问题中有很多关于博客、帖子的内容...但是这与您的表格之间存在脱节...什么表格存储什么...博客数据在哪里...帖子在哪里数据...??你谈了这么多的链接在哪里存储在表中......? 提示:如果您正在尝试解决技术难题...尝试保留域详细信息...这将减少您的问题的大小,并且它也将真正帮助其他人提供快速回答... @Mulki post_id 指的是博客文章,website_id 指的是博客站点。除了这些之外,或多或少的字段都可以忽略 - test_smartlink_to_websites 是关键表,其中记录了以前的帖子与网站的关系。 【参考方案1】:

如果我错了,请纠正我。看来您的任务是确定有向图中的周期。它并不像看起来那么复杂。请参阅此博客文章了解它是如何在 SQL 中完成的:http://devio.wordpress.com/2009/09/13/finding-cycles-in-directed-graphs-using-tsql/。另请参阅此链接以了解 SQL 中的广度优先搜索:http://willets.org/sqlgraphs.html

已编辑:为清晰和理解有向无环图和循环图添加了图像。

例如,这与您的情况相似。它不是单个图,而是一组图(如果它们是树,则为森林)。注意没有共同的根。它只是以某种方式连接的节点。在较大的子图中有一个循环,节点相互引用。如果去掉向上的链接,子图就变成了无环的。

【讨论】:

感谢您的链接。我已经阅读了内容,老实说,我不理解其中的一些复杂之处——但是我认为那里描述的问题要复杂一些。我只需要从一组记录的关系中建立,如果站点 A 链接到 B,B 不能链接到 A ...并返回站点链接的所有潜在有效排列。 那是我的第一印象...但帖子中的示例显示其他内容...请注意示例中的“站点 B 可以链接到站点 D”...因为 d 链接到 A 并且A 到 B 使其循环......但允许......看起来他只是在寻找引用......任何具有向后引用的东西 @BrynJ:嗯……这就是有向图。 A,C->B->D 和一个循环 A,C->B->D->C,F。试着把它画出来,它会更清晰。 为了清晰起见,我添加了一张图片。

以上是关于处理复杂关系的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL之复杂查询与视图

SQL之复杂查询与视图

两表对应关系的复杂SQL查询

sql 复杂查询 以teacher student course多对多关系为例

数据库是怎样炼成的:查询处理优化篇

Mybatis关于复杂的SQL查询的处理&Mybatis的缓存机制