基于CASE的SQL日期比较问题:MTD报表适配月初场景
解决月度截至当日(MTD)日期列表生成问题
问题根源
你用GETDATE()和当月第一天做比较时,GETDATE()返回带时分秒的datetime类型,而当月第一天是纯date类型,直接相等判断永远不成立,这就是CASE逻辑失效的核心原因。
修正后的完整代码
DECLARE @Date1 DATE, @Date2 DATE -- 确定起始日期:当日为当月1号则取上月第一天,否则取当月第一天 SET @Date1 = CASE WHEN CAST(GETDATE() AS DATE) = DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) THEN DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()) - 1, 1) ELSE DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) END -- 确定结束日期:当日为当月1号则取上月最后一天,否则取当日 SET @Date2 = CASE WHEN CAST(GETDATE() AS DATE) = DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) THEN EOMONTH(DATEADD(MONTH, -1, GETDATE())) ELSE CAST(GETDATE() AS DATE) END -- 生成连续日期列表 SELECT DATEADD(DAY, number, @Date1) AS [Date] FROM master..spt_values WHERE type = 'P' AND DATEADD(DAY, number, @Date1) <= @Date2 ORDER BY [Date] ASC
关键优化说明
- 用
CAST(GETDATE() AS DATE)剥离时间部分,确保和纯日期的当月第一天能正确匹配 - 改用
DATEFROMPARTS生成日期,比嵌套DATEADD更直观易维护 - 调整日期生成逻辑:原代码的
number+1会跳过起始日期,改为直接用number确保起始日被包含 - 结束日期适配:当月1号时自动取上月月末,保证返回上月全量日期;其他日期取当日,符合MTD的查询需求
测试场景验证
- 非当月1号(如4月15日):生成4月1日至4月15日的完整日期列表
- 当月1号(如5月1日):自动返回4月1日至4月30日的全量日期
内容的提问来源于stack exchange,提问作者Lwazi Mace
相关产品推荐
相关产品推荐

