声明变量遍历RDD列计算FDW时Case表达式异常问题排查
问题分析:SQL日期计算逻辑异常原因及修复
问题场景
需求为:对tableA的RDD列每行数据执行日期计算,规则如下:
- 返回该日期所在周的首日(每周首日为周日)
- 若该日期的周跨月(即周首日属于上月),则返回当月首日
执行下方SQL后,所有行的FDW字段返回同一个错误日期,但单独测试单日期时,Case表达式逻辑正常。
错误SQL代码
DECLARE @tbl TABLE ( RDD date ) INSERT INTO @tbl SELECT RDD FROM tableA DECLARE @testdate date SELECT @testdate = RDD FROM @tbl SELECT CASE WHEN MONTH(@testdate) = MONTH(DATEADD(day, 1-DATEPART(weekday, @testdate), @testdate)) THEN DATEADD(day, 1-DATEPART(weekday, @testdate), @testdate) ELSE DATEADD(month, DATEDIFF(month, 0, @testdate), 0) END AS FDW, RDD, BPN FROM tableA WHERE RDD IS NOT NULL GROUP BY RDD, BPN
错误输出
| FDW | RDD |
|---|---|
| 2023-08-27 00:00:00:000 | 2024-06-19 |
| 2023-08-27 00:00:00:000 | 2024-02-22 |
单日期测试正确代码
DECLARE @TESTDATE DATE = '2024-06-19' select case when month(@testdate) = month(dateadd(day,1-datepart(weekday,@testdate),@testdate)) then dateadd(day,1-datepart(weekday,@testdate),@testdate) else DATEADD(month, DATEDIFF(month,0,@testdate),0) end
问题原因
- 变量赋值逻辑错误:
SELECT @testdate = RDD FROM @tbl语句中,当@tbl包含多条记录时,该赋值方式只会将最后一条(或数据库默认排序下的某一条)记录的RDD值赋值给@testdate,而非每行对应各自的RDD值。 - Case表达式未关联当前行数据:后续查询中,Case表达式使用的是固定的
@testdate变量值,而非当前行的RDD字段,导致所有行的FDW计算都基于同一个错误日期,结果全部相同。 - 冗余临时表:创建
@tbl临时表的操作完全多余,未起到任何实际作用,反而增加了不必要的性能开销。
修复后的SQL代码
SELECT CASE WHEN MONTH(RDD) = MONTH(DATEADD(day, 1-DATEPART(weekday, RDD), RDD)) THEN DATEADD(day, 1-DATEPART(weekday, RDD), RDD) ELSE DATEADD(month, DATEDIFF(month, 0, RDD), 0) END AS FDW, RDD, BPN FROM tableA WHERE RDD IS NOT NULL GROUP BY RDD, BPN
内容的提问来源于stack exchange,提问作者brins
相关产品推荐
相关产品推荐

