Amazon Redshift日期计算异常咨询:为何未返回正确日期2017-10-31?
Redshift日期计算异常:为什么得到2017-10-30而不是2017-10-31?
嘿,这个问题我之前也踩过坑,其实这不是Redshift的Bug,是它的dateadd函数处理月份时的特定逻辑导致的,咱们一步步拆解来看:
首先还原你的查询和结果:
执行SQL:
select dateadd(month, -6, dateadd(day, -2, date('20180503')) ) AS "this is 1nov17", dateadd(month, -6, dateadd(day, -3, date('20180503')) ) AS "should be 31oct17"输出结果:
this is 1nov17 should be 31oct17 2017-11-01 00:00:00.0 2017-10-30 00:00:00.0
问题根源:Redshift的dateadd(month)逻辑
Redshift的dateadd(month, N, 日期)函数遵循「保留原日期日部分」的规则:
- 先调整月份(加上/减去N个月)
- 如果新月份存在原日期的日数,直接保留该日;
- 如果新月份不存在原日期的日数,才会自动回退到新月份的最后一天。
咱们来算你的第二个字段:
- 内层
dateadd(day, -3, '2018-05-03')得到2018-04-30(因为5月3日减3天是4月30日,4月只有30天) - 然后
dateadd(month, -6, '2018-04-30'):月份减6是2017年10月,10月有30号,所以直接保留日数30,得到2017-10-30
而你预期的是2017-10-31,本质是想获取「2017年11月1日的前一天」,但你的计算路径刚好触发了Redshift的日数保留规则,导致结果偏差。
正确的实现方式
如果你想得到2017-10-31,有两种更可靠的写法:
写法1:先定位到2017-11-01,再减1天
先计算出2018-05-03往前推6个月的对应日期(2017-11-03),再调整到11月1日,最后减1天:
select dateadd(month, -6, dateadd(day, -2, date('20180503')) ) AS "this is 1nov17", dateadd(day, -1, dateadd(month, -6, date('20180501')) ) AS "correct 31oct17"
写法2:用last_day直接获取目标月份的最后一天
直接计算2017年10月的最后一天:
select dateadd(month, -6, dateadd(day, -2, date('20180503')) ) AS "this is 1nov17", last_day(dateadd(month, -7, date('20180503')) ) AS "correct 31oct17"
(注:2018-05减7个月是2017-10,last_day会直接返回该月最后一天2017-10-31)
内容的提问来源于stack exchange,提问作者Ratnesh Sharma
相关产品推荐
相关产品推荐

