Redshift SQL中如何为非闰年跳过2月29日以计算财年日数和财季日数
Redshift SQL中如何为非闰年跳过2月29日以计算财年日数和财季日数
嘿,这个需求我之前做财务日历的时候刚好碰到过,在Redshift里咱们可以通过日期函数结合CASE逻辑来实现,完全贴合你的要求,我给你拆解一下具体的实现步骤:
一、计算Fiscal_year_day_nr
核心思路是:闰年直接用一年中的自然日数(DOY),非闰年则对3月1日及以后的日期额外加1天,模拟跳过2月29日的位置。
具体SQL逻辑如下:
SELECT date, CASE -- 判断是否为闰年:能被4整除但不能被100整除,或能被400整除 WHEN EXTRACT(YEAR FROM date) % 4 = 0 AND (EXTRACT(YEAR FROM date) % 100 != 0 OR EXTRACT(YEAR FROM date) % 400 = 0) THEN EXTRACT(DOY FROM date) -- 闰年直接取自然日数,2月29日就是第60天 -- 非闰年且日期在3月1日及以后,日数加1 WHEN date >= DATE_TRUNC('year', date) + INTERVAL '2 months' THEN EXTRACT(DOY FROM date) + 1 -- 非闰年且在3月1日之前,直接取自然日数 ELSE EXTRACT(DOY FROM date) END AS Fiscal_year_day_nr FROM calendar;
测试一下你关心的几个日期:
- 非闰年2023-02-28:返回59
- 非闰年2023-03-01:返回61
- 闰年2024-02-29:返回60
- 闰年2024-03-01:返回61
完全符合你要的效果!
二、计算Fiscal_quarter_daynr
这部分需要和财年日数的逻辑保持一致,非闰年的Q1要跳过2月29日的位置,让Q1总天数为91天(对应财年366天的划分:91+91+92+92)。
我们可以先通过CTE把基础信息计算出来,再处理财季日数:
WITH calendar_base AS ( SELECT date, -- 判断是否为闰年 EXTRACT(YEAR FROM date) % 4 = 0 AND (EXTRACT(YEAR FROM date) % 100 != 0 OR EXTRACT(YEAR FROM date) % 400 = 0) AS is_leap_year, -- 获取当前日期所在财季的起始日 DATE_TRUNC('quarter', date) AS fiscal_quarter_start, -- 获取当前季度 EXTRACT(QUARTER FROM date) AS fiscal_quarter FROM calendar ) SELECT date, -- 复用财年日数的计算逻辑 CASE WHEN is_leap_year THEN EXTRACT(DOY FROM date) WHEN date >= DATE_TRUNC('year', date) + INTERVAL '2 months' THEN EXTRACT(DOY FROM date) + 1 ELSE EXTRACT(DOY FROM date) END AS Fiscal_year_day_nr, -- 计算财季日数 CASE -- 闰年所有季度直接用「日期与季度起始日的间隔天数+1」 WHEN is_leap_year THEN DATEDIFF(day, fiscal_quarter_start, date) + 1 -- 非闰年Q1且日期在3月1日及以后,间隔天数+1后再加1(跳过2月29日) WHEN fiscal_quarter = 1 AND date >= DATE_TRUNC('year', date) + INTERVAL '2 months' THEN DATEDIFF(day, fiscal_quarter_start, date) + 2 -- 其他非闰年情况直接用间隔天数+1 ELSE DATEDIFF(day, fiscal_quarter_start, date) + 1 END AS Fiscal_quarter_daynr FROM calendar_base;
同样测试关键日期:
- 非闰年2023-02-28:财季日数返回59
- 非闰年2023-03-01:财季日数返回61
- 闰年2024-02-29:财季日数返回60
- 闰年2024-03-01:财季日数返回61
这样两个字段就都满足你的需求了。
备注:内容来源于stack exchange,提问作者Dawid_K
相关产品推荐
相关产品推荐

