SQL跨年获取上月数据:CASE WHEN语句编写求助
解决跨年场景下SQL获取上月数据的问题
要筛选出属于上月的数据,需同时匹配创建时间的年份和月份,尤其要处理跨年情况(比如当前是1月时,上月为去年12月)。你提供的CASE语句存在语法错误,且逻辑未覆盖完整的年月判断逻辑,以下是修正方案:
核心思路
判断创建时间是否属于上月,分两种场景处理:
- 当前月份不为1月:上月是「当前年份的当前月份-1」
- 当前月份为1月:上月是「去年的12月」
修正后的CASE实现(分步计算)
先统一计算转换时区后的当前日期信息,再通过CASE推导上月的年月,最后进行匹配:
WITH current_date_ist AS ( SELECT DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', GETDATE())) AS current_date, EXTRACT(YEAR FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', GETDATE()))) AS current_year, EXTRACT(MONTH FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', GETDATE()))) AS current_month ) SELECT u.*, EXTRACT(YEAR FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', u.createdTime))) AS createdYear, EXTRACT(MONTH FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', u.createdTime))) AS createdMonth, -- 计算上月年份 CASE WHEN current_month = 1 THEN current_year - 1 ELSE current_year END AS last_month_year, -- 计算上月月份 CASE WHEN current_month = 1 THEN 12 ELSE current_month - 1 END AS last_month_num FROM your_table u, current_date_ist -- 筛选上月数据 WHERE EXTRACT(YEAR FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', u.createdTime))) = CASE WHEN current_month = 1 THEN current_year - 1 ELSE current_year END AND EXTRACT(MONTH FROM DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', u.createdTime))) = CASE WHEN current_month = 1 THEN 12 ELSE current_month - 1 END;
简化写法(利用日期函数自动处理)
如果你的SQL引擎支持日期截断和加减函数(如Snowflake、PostgreSQL等),可以直接生成上月的日期范围,无需手动计算年月:
SELECT u.* FROM your_table u WHERE DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', u.createdTime)) BETWEEN DATE_TRUNC('MONTH', DATEADD('MONTH', -1, DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', GETDATE())))) AND LAST_DAY(DATEADD('MONTH', -1, DATE(CONVERT_TIMEZONE('UTC', 'IST-05:30', GETDATE()))));
这种写法会自动处理跨年逻辑,代码更简洁可靠。
原代码问题说明
- 语法错误:嵌套CASE未正确使用
END闭合,第一个CASE缺少结束标记,第二个CASE的逻辑也未完成闭合 - 逻辑缺失:仅处理了月份为0的情况,但未对应调整年份,导致跨年场景下年份匹配错误
内容的提问来源于stack exchange,提问作者Lucifer
相关产品推荐
相关产品推荐

