如何查询SQL Server中本月未提交数据的部门?
解决SQL Server中获取本月未提交数据部门的问题
问题分析
你用NOT IN结合两个查询未成功,大概率是因为第二个查询返回的结果中存在NULL值(NOT IN遇到NULL会直接返回空集),另外原有的日期判断语句也可以优化,避免影响查询性能。
优化后的解决方案
方案1:使用NOT EXISTS(推荐,性能更优)
NOT EXISTS在处理NULL时不会出现异常,同时我们优化日期条件(避免在列上调用函数,可利用索引提升效率):
SELECT DISTINCT a.Department FROM ( SELECT Department FROM EmployeeFollowupManagerCommit UNION ALL SELECT Department FROM EmploymentUser ) a WHERE NOT EXISTS ( SELECT 1 FROM EmployeeFollowupManagerCommit e WHERE e.Department = a.Department AND e.CommitDateTime >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) AND e.CommitDateTime < DATEADD(MONTH, 1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)) ) ORDER BY a.Department;
方案2:修正NOT IN的写法(需确保无NULL值)
如果要继续使用NOT IN,需要先排除子查询中的NULL部门,同时优化日期判断:
SELECT DISTINCT Department FROM ( SELECT Department FROM EmployeeFollowupManagerCommit UNION ALL SELECT Department FROM EmploymentUser ) a WHERE Department NOT IN ( SELECT Department FROM EmployeeFollowupManagerCommit WHERE CommitDateTime >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) AND CommitDateTime < DATEADD(MONTH, 1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)) AND Department IS NOT NULL -- 强制排除NULL值 ) ORDER BY Department;
日期条件优化说明
你原来的日期判断逻辑:
WHERE (Month(CommitDateTime) <= Month((getdate())) AND Month(CommitDateTime) >= Month((getdate()))) AND (YEAR(CommitDateTime) <= YEAR((getdate())) AND YEAR(CommitDateTime) >= YEAR((getdate())))
可以简化为直接判断日期范围,这种写法不会在CommitDateTime列上调用函数,能利用该列的索引,大幅提升查询性能:
WHERE CommitDateTime >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) AND CommitDateTime < DATEADD(MONTH, 1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
额外提示
- 内层用
UNION ALL比UNION更高效,因为它不会做重复值过滤,外层已经用DISTINCT去重,所以内层无需额外处理。 - 如果
EmploymentUser或EmployeeFollowupManagerCommit表中的Department字段可能为NULL,记得在外层查询中加上AND a.Department IS NOT NULL,避免无效的NULL部门出现在结果里。
内容的提问来源于stack exchange,提问作者StigK
相关产品推荐
相关产品推荐

