查询自引用表中所有连接的祖先和后代

Posted

技术标签:

【中文标题】查询自引用表中所有连接的祖先和后代【英文标题】:Query all connected ancestors and descendants in a self referencing table 【发布时间】:2021-03-18 17:17:06 【问题描述】:

假设我有一个表 'prlines' 与相邻记录的自关系:

id | prev_id
------------
1  | NULL
2  | NULL
3  | 1
4  | 2
5  | 3
6  | 5

我想获取某个记录的所有连接 ID(上一个/下一个)。例如:

SELECT `prev_id` FROM `prlines` ... WHERE id = 5;

应该产生这个输出:

prev_id
-------
3
1
6

我目前正在做的是在 python 中创建一个 while 循环,它会生成多个查询来跟踪每条记录的关系。有什么想法可以在单个 mysql 查询中实现这一点吗?

【问题讨论】:

【参考方案1】:

您可以使用递归 cte:

with recursive cte(p, c, f) as (
   select p.*, p.prev_id = 5 from prlines p where p.id = 5 or p.prev_id = 5
   union all
   select p.*, c.f from cte c join prlines p on case when c.f then p.prev_id = c.p else p.id = c.c end
)
select case when f then p else c end prev_id from cte where c is not null order by f;

输出:

prev_id
3
1
6
7

见demo。

【讨论】:

很好,但是它也可以向前爬行吗?它只前进了一步。如果我添加一个新行 (id:7, prev_id:6) 它应该被包括在内,但它不是。

以上是关于查询自引用表中所有连接的祖先和后代的主要内容,如果未能解决你的问题,请参考以下文章

如何通过内部连接优化自连接选择到另一个表

单个查询中的 Postgresql 多个连接,其中连接的外键不存在于所有表中

祖先查询直接后代 - Google 数据存储

Mysql中的关联查询(内连接,外连接,自连接)

多表查询-概述

Mysql中的关联查询(内连接,外连接,自连接)