使用SQL Cursor迭代查找间隔超45天的重复记录日期
我来帮你搞定这个SQL游标的迭代查找需求,先理清楚核心逻辑,再修正并优化你提供的代码,确保它能准确完成任务。
需求明确
我们要实现的核心逻辑是:
- 针对每条
quote_reference的入库记录,从首次入库日期开始,找到与其间隔超过45天的下一个入库日期 - 将找到的这个日期作为新的起始点,重复上述查找过程,直到没有符合条件的日期为止
- 同时标记出哪些日期是符合「与上一个有效起始日期间隔超过45天」的记录(标记为
Y),不符合的标记为N
现有代码的问题分析
你提供的游标代码存在几个关键问题:
- 游标
FETCH的字段与声明的变量不匹配(声明了3个变量,但后续FETCH又加入了@policyNo) - 没有实现迭代更新起始日期的核心逻辑,只是简单判断当前记录的
diff值,无法完成递进查找 - 变量赋值逻辑混乱,没有按
quote_reference分组处理不同的记录
改进后的SQL游标实现
下面是修正后的代码,完全贴合需求逻辑:
-- 先初始化counts字段为'N',避免初始值混乱 UPDATE #temp1 SET counts = 'N'; -- 声明所需变量 Declare @currentQuote NVARCHAR(20) Declare @startDate DATE Declare @nextDate DATE Declare @prevQuote NVARCHAR(20) = '' -- 按quote_reference和入库日期升序排序,确保处理顺序正确 Declare DateCursor Cursor FOR SELECT quote_reference, Miscellaneous_TodaysDate FROM #temp1 ORDER BY quote_reference, Miscellaneous_TodaysDate OPEN DateCursor FETCH NEXT FROM DateCursor INTO @currentQuote, @nextDate WHILE(@@FETCH_STATUS = 0) BEGIN -- 切换到新的quote_reference时,重置起始日期为第一条记录的日期 IF @currentQuote <> @prevQuote BEGIN SET @startDate = @nextDate; -- 首次记录标记为'Y'(作为该引用的第一个有效起始点) UPDATE #temp1 SET counts = 'Y' WHERE quote_reference = @currentQuote AND Miscellaneous_TodaysDate = @startDate; SET @prevQuote = @currentQuote; END ELSE BEGIN -- 计算当前日期与当前起始日期的间隔天数 DECLARE @dayDiff INT = DATEDIFF(DAY, @startDate, @nextDate); -- 如果间隔超过45天,标记为'Y'并更新起始日期 IF @dayDiff > 45 BEGIN UPDATE #temp1 SET counts = 'Y' WHERE quote_reference = @currentQuote AND Miscellaneous_TodaysDate = @nextDate; SET @startDate = @nextDate; END -- 间隔不足45天的记录保持'N'标记 END FETCH NEXT FROM DateCursor INTO @currentQuote, @nextDate END CLOSE DateCursor DEALLOCATE DateCursor
代码逻辑详解
- 初始化处理:先把所有记录的
counts设为N,避免初始值干扰结果 - 游标排序规则:按
quote_reference分组、日期升序排序,确保我们按入库顺序处理每条记录 - 分组起始处理:遇到新的
quote_reference时,将它的第一条入库日期设为起始点,并标记为Y - 迭代查找逻辑:对后续每条记录,计算它与当前起始日期的间隔:
- 间隔>45天:标记为
Y,并将该日期更新为新的起始点 - 间隔≤45天:保持
N标记,不更新起始点
- 间隔>45天:标记为
示例数据演示
假设某quote_reference的入库记录如下:
| quote_reference | Miscellaneous_TodaysDate |
|---|---|
| Q12345 | 2021-05-31 |
| Q12345 | 2021-07-10 |
| Q12345 | 2021-08-03 |
| Q12345 | 2021-09-20 |
处理过程:
- 第一条记录(2021-05-31)作为起始点,标记为
Y - 第二条记录(2021-07-10)与起始日期间隔40天,不足45天,标记为
N - 第三条记录(2021-08-03)与起始日期间隔64天,超过45天,标记为
Y,并将起始日期更新为2021-08-03 - 第四条记录(2021-09-20)与新起始日期间隔48天,超过45天,标记为
Y,更新起始日期为2021-09-20
最终counts字段结果:
| quote_reference | Miscellaneous_TodaysDate | counts |
|---|---|---|
| Q12345 | 2021-05-31 | Y |
| Q12345 | 2021-07-10 | N |
| Q12345 | 2021-08-03 | Y |
| Q12345 | 2021-09-20 | Y |
内容的提问来源于stack exchange,提问作者Anurag Chaturvedi
相关产品推荐
相关产品推荐

