SQL多表嵌套关联查询Tab1无对应Tab4记录的实现方法
链式关联表反向查询无终表记录的根表方案
核心逻辑
需求是筛选出沿Tab1→Tab2→Tab3→Tab4的关联链路,完全不存在任何对应Tab4记录的Tab1数据,核心判断规则是:只要某条Tab1记录下任意层级的关联分支能连通到Tab4,就将其排除,剩余记录即为符合要求的结果。
不要单独查询无Tab4的Tab3记录再向上回溯,这种方式会漏掉中间关联层断链的场景(比如Tab2没有对应Tab3记录的分支,本身就满足无Tab4的要求)。
推荐实现(NOT EXISTS 写法)
这种写法可读性强,大部分数据库引擎会自动做关联短路优化,查询性能更好:
SELECT t1.id FROM Tab1 t1 WHERE NOT EXISTS ( SELECT 1 FROM Tab2 t2 INNER JOIN Tab3 t3 ON t3.Tab2Id = t2.id INNER JOIN Tab4 t4 ON t4.Tab3Id = t3.id WHERE t2.Tab1Id = t1.id );
逻辑说明:子查询会遍历当前Tab1下所有关联分支,只要存在任意一条能连通到Tab4的链路,NOT EXISTS判断就不成立,该Tab1记录会被过滤。
备选实现(左连接+聚合判断写法)
适合习惯使用外连接逻辑的场景,注意聚合统计时必须使用Tab4的非空字段(比如主键id):
SELECT t1.id FROM Tab1 t1 LEFT JOIN Tab2 t2 ON t2.Tab1Id = t1.id LEFT JOIN Tab3 t3 ON t3.Tab2Id = t2.id LEFT JOIN Tab4 t4 ON t4.Tab3Id = t3.id GROUP BY t1.id HAVING COUNT(t4.id) = 0;
逻辑说明:左连接会保留所有链路的关联结果,没有匹配到Tab4的记录中t4字段值为NULL,COUNT(t4.id)不会统计NULL值,计数为0即代表该Tab1下没有任何能连通到Tab4的分支。
测试数据验证
用题目给出的测试样例执行上述SQL:
- Tab1 id=1:关联的Tab2 id=10下存在Tab3 id=100,该Tab3记录能关联到Tab4 id=1000,因此被过滤
- Tab1 id=2:关联的Tab2 id=30、40均无对应Tab3记录,全程无法连通到Tab4,因此被返回,完全符合预期结果。
内容的提问来源于stack exchange,提问作者Kay S
相关产品推荐
相关产品推荐

