SQL查询问题:筛选指定日期范围内候选者最新状态变更记录
问题分析与修正方案
首先看你遇到的几个核心问题:
逻辑运算符优先级错误:SQL里
AND的优先级比OR高,你原语句里的WHERE条件实际会被解析成:newstatus = 'Working Compliant' OR (newstatus = 'Registered Compliant' AND A.Date BETWEEN @rangefrom AND @Rangetill)这就导致
Working Compliant的记录不管日期是否在范围内都会被返回,完全不符合你的预期。日期范围顺序搞反了:你设置
@rangefrom = DATEADD(day, -50, GETDATE())(也就是50天前),@Rangetill = DATEADD(day, -90, GETDATE())(90天前),但BETWEEN要求左边的日期必须小于等于右边的日期,你的范围相当于要求日期在50天前到90天前,这是一个反向的范围,根本不会匹配任何数据(因为90天前比50天更早)。子查询逻辑有漏洞:原查询的子查询是找每个候选者的最新变更日期,但没有限定这个最新日期必须落在你指定的范围内——也就是说,如果某个候选者的最新状态变更不在目标日期区间里,原语句可能还是会返回它(如果它在范围内有符合状态的记录),这也不符合你要“指定日期范围内候选者的最新状态变更”的需求。
修正后的SQL方案
方案1:修正原查询的逻辑问题
先调整日期范围的赋值,然后给OR条件加括号,再确保子查询的日期也在范围内:
Declare @Rangefrom date, @Rangetill date; -- 交换起始和结束,让@Rangefrom是更早的日期(90天前),@Rangetill是更近的(50天前) SET @rangefrom = DATEADD(day, -90, GETDATE()) SET @Rangetill = DATEADD(day, -50, GETDATE()) Select a.Candidate, a.Newstatus, @rangefrom, a.date, @rangetill, a.Consultant From AppStatusHistory as A WHERE (newstatus = 'Working Compliant' OR newstatus = 'Registered Compliant') -- 给OR条件加括号 AND A.Date BETWEEN @rangefrom AND @Rangetill AND A.Date = ( select max(B.date) from AppStatusHistory AS B where B.Candidate = a.Candidate AND B.Date BETWEEN @rangefrom AND @Rangetill -- 子查询也限定日期范围,确保最新日期在区间内 AND (B.newstatus = 'Working Compliant' OR B.newstatus = 'Registered Compliant') -- 子查询也限定状态 )
方案2:用窗口函数(更清晰易维护)
用ROW_NUMBER()窗口函数按候选者分组,按日期降序排序,然后取每个组的第一条记录,同时过滤状态和日期范围:
Declare @Rangefrom date, @Rangetill date; SET @rangefrom = DATEADD(day, -90, GETDATE()) SET @Rangetill = DATEADD(day, -50, GETDATE()) WITH RankedStatusChanges AS ( SELECT Candidate, Newstatus, Date, Consultant, -- 按候选者分组,日期最新的排第1 ROW_NUMBER() OVER (PARTITION BY Candidate ORDER BY Date DESC) AS rn FROM AppStatusHistory WHERE (newstatus = 'Working Compliant' OR newstatus = 'Registered Compliant') AND Date BETWEEN @rangefrom AND @Rangetill ) SELECT Candidate, Newstatus, @rangefrom AS RangeFrom, Date, @Rangetill AS RangeTill, Consultant FROM RankedStatusChanges WHERE rn = 1; -- 只取每个候选者的最新记录
这个方案的优势是逻辑更直观,避免了子查询可能带来的性能问题(尤其是当表数据量大的时候),也更容易维护和修改条件。
内容的提问来源于stack exchange,提问作者A.Chandler
相关产品推荐
相关产品推荐

