技术求助:如何编写获取不匹配JOIN条件记录的SQL视图
获取不匹配JOIN关联条件的SQL视图调整方案
我来帮你搞定这个需求!要获取原视图中不满足JOIN关联+筛选条件的记录,我们有两种常用且可靠的方法,结合你提供的原有代码,具体实现如下:
方法一:LEFT JOIN + IS NULL 检测关联失败
这种方法通过左连接保留主表(AeoiSdtTemp)的所有记录,然后筛选出无法匹配关联表条件的行。注意要把原视图中针对关联表的筛选条件移到JOIN的ON子句中,避免左连接被自动转换成内连接:
ALTER VIEW [dbo].[vAeoiCaseClose] AS SELECT s.CaseReference, s.AccessNumber FROM dbo.AeoiSdtTemp s -- 左连接AeoiCaseManagement,同时带上原视图中c的筛选条件 LEFT JOIN AeoiCaseManagement c ON c.AccessNumber = s.AccessNumber AND c.StatusCode = 15 -- 左连接AeoiCaptureLog,带上原视图中a的筛选条件 LEFT JOIN AeoiCaptureLog a ON a.AccessNumber = c.AccessNumber AND a.AscertainMethodId IS NOT NULL AND a.StatusCode IN (6, 13, 15) -- 筛选出两种不匹配的情况:要么没关联到c,要么关联到c但没找到符合条件的a WHERE c.AccessNumber IS NULL OR a.AccessNumber IS NULL -- 如果你原视图中有未写完的DATEDIFF条件,补充在这里即可,比如: -- AND DATEDIFF(dd, s.CreateDate, GETDATE()) > 30
方法二:NOT EXISTS 子查询(性能更优)
如果你的表有合适的索引,NOT EXISTS通常会比左连接更快,因为它一旦找到第一个不匹配的记录就会停止查询,逻辑也更直观——直接找出主表中不存在符合原关联+筛选条件的记录:
ALTER VIEW [dbo].[vAeoiCaseClose] AS SELECT s.CaseReference, s.AccessNumber FROM dbo.AeoiSdtTemp s WHERE NOT EXISTS ( SELECT 1 FROM AeoiCaseManagement c JOIN AeoiCaptureLog a ON a.AccessNumber = c.AccessNumber WHERE c.AccessNumber = s.AccessNumber AND c.StatusCode = 15 AND a.AscertainMethodId IS NOT NULL AND a.StatusCode IN (6, 13, 15) -- 原视图的DATEDIFF条件补充到这里,比如: -- AND DATEDIFF(dd, s.CreateDate, GETDATE()) > 30 )
小提示
- 如果需要查看关联表中的具体字段(比如想知道为什么不匹配,比如
c.StatusCode实际是什么值),优先用方法一; - 如果只需要主表的记录,追求性能的话优先用方法二;
- 记得把原视图中未写完的
DATEDIFF条件补充到对应的位置,确保逻辑完整。
内容的提问来源于stack exchange,提问作者Maverick
相关产品推荐
相关产品推荐

