SQL Server中按OpenDt动态获取此前1-2个月数据的查询未生效问题
问题根因
BETWEEN 语法的强制要求是左端点必须为区间最小值,右端点必须为区间最大值,若两端点顺序写反,SQL会将其识别为不存在的无效区间,直接返回空结果集。
你当前的查询语句:
select * from dbo.mytable where Valdate between OpenDt and dateadd(Month,-1,OpenDt)
其中dateadd(Month,-1,OpenDt)计算得到的是比OpenDt更早的时间,相当于你写的区间是「从更大的时间值OpenDt,到更小的时间值OpenDt减1个月」,顺序完全颠倒,因此无法返回有效结果。
而你之前测试传入正参数时,比如使用between OpenDt and dateadd(Month,1,OpenDt),此时左值更小、右值更大,区间逻辑成立,因此可以正常返回OpenDt之后的记录。
适配需求的正确写法
根据你要获取OpenDt之前历史数据的目标,调整区间端点顺序即可:
- 需获取OpenDt往前1个月内的所有Valdate记录(即Valdate落在
[OpenDt-1个月, OpenDt]区间):
直接颠倒BETWEEN的两个端点顺序,写法为:select * from dbo.mytable where Valdate between dateadd(Month,-1,OpenDt) and OpenDt - 需获取OpenDt往前1~2个月的历史记录(即Valdate落在
[OpenDt-2个月, OpenDt-1个月]区间):select * from dbo.mytable where Valdate between dateadd(Month,-2,OpenDt) and dateadd(Month,-1,OpenDt)
高可读性的稳妥写法
为了避免后续编写语句时再次搞反区间顺序,可直接使用比较运算符拼接查询条件,逻辑更直观:
- 匹配OpenDt前1个月范围内的记录:
select * from dbo.mytable where Valdate >= dateadd(Month, -1, OpenDt) and Valdate <= OpenDt - 匹配OpenDt前1至2个月的记录:
select * from dbo.mytable where Valdate >= dateadd(Month, -2, OpenDt) and Valdate < dateadd(Month, -1, OpenDt)
注意:如果
Valdate/OpenDt字段为带时分秒的datetime类型,建议边界条件使用<替代<=,避免出现边界时间匹配偏差的问题。
内容的提问来源于stack exchange,提问作者Tayyab Vohra
相关产品推荐
相关产品推荐

