SQL递归层级查询:基于TblMatrix表的ApproverId反向关联查询
递归层级查询实现:根据ApproverId追溯关联ID列表
我来帮你搞定这个递归层级查询的需求~首先咱们先明确下场景:你有一张TblMatrix表,存储了ID和对应的审批人ID的关联关系,现在需要传入任意审批人ID,返回所有间接关联的上级ID列表(也就是向上追溯整个审批链)。
先确认下你的表结构和数据:
-- 表结构 CREATE TABLE TblMatrix ( ID INT, ApproverId INT ); -- 测试数据 INSERT INTO TblMatrix VALUES (1, 4), (2, 7), (7, 8), (4, 5), (5, 6);
接下来分不同数据库给出实现方案:
方案1:支持递归CTE的数据库(SQL Server、MySQL 8.0+、PostgreSQL)
这类数据库可以用**递归公共表表达式(CTE)**来实现层级追溯,代码逻辑清晰易懂:
-- 示例:传入ApproverId = 6,返回对应的ID列表 WITH RecursiveApprovers AS ( -- 锚点查询:找到直接关联的ID(即ApproverId等于目标值的记录) SELECT ID FROM TblMatrix WHERE ApproverId = 6 UNION ALL -- 递归查询:向上追溯,把当前找到的ID作为新的ApproverId,继续查找上级ID SELECT tm.ID FROM TblMatrix tm INNER JOIN RecursiveApprovers ra ON tm.ApproverId = ra.ID ) SELECT ID FROM RecursiveApprovers;
执行这段代码后,返回结果就是:
ID --- 5 4 1
如果要查询ApproverId=8的情况,只需要把WHERE ApproverId = 6改成WHERE ApproverId = 8,就能得到:
ID --- 7 2
可选:防止递归循环
如果你的表可能存在循环引用(比如ID=6的ApproverId=1,形成闭环),可以限制递归深度避免报错:
WITH RecursiveApprovers AS ( SELECT ID FROM TblMatrix WHERE ApproverId = 6 UNION ALL SELECT tm.ID FROM TblMatrix tm INNER JOIN RecursiveApprovers ra ON tm.ApproverId = ra.ID ) SELECT ID FROM RecursiveApprovers OPTION (MAXRECURSION 100); -- 限制最大递归深度为100,可按需调整
方案2:Oracle数据库
Oracle有专门的层级查询语法CONNECT BY,写法更简洁:
-- 示例:传入ApproverId=6 SELECT ID FROM TblMatrix START WITH ApproverId = 6 -- 指定起始条件 CONNECT BY PRIOR ID = ApproverId; -- 递归关联条件:上一层的ID是当前行的ApproverId
同样,替换START WITH里的数值就能查询不同ApproverId对应的结果。
内容的提问来源于stack exchange,提问作者punter




