如何在递归SQL中为Fiscal日期表生成正确的Actual Date列?
解决递归CTE生成逐天递增Actual Date的问题
我明白你的需求了——你需要让Actual Date从BEGIN_DATE开始每天递增,和Fiscal Day一一对应(Fiscal Day=1对应BEGIN_DATE,Fiscal Day=2对应BEGIN_DATE+1天,以此类推)。咱们来一步步修正你的查询:
问题分析
你的现有递归CTE里,BEGIN_DATE和END_DATE一直沿用原始表的固定值,没有生成动态递增的日期;而你的错误尝试里,初始用了current_date(这完全不符合需求,应该用BEGIN_DATE),后续的ACTUAL_DATE+FISCAL_DAY会导致日期跳变(比如Fiscal Day=2时直接加2天,跳过了中间的一天),这显然不是你要的效果。
正确的递归CTE写法
核心思路是:
- 锚点成员中,把
Actual Date初始化为BEGIN_DATE,对应Fiscal Day=1 - 递归成员中,每次给
Actual Date加1天,同时Fiscal Day加1 - 终止条件改为判断
Actual Date < END_DATE(确保生成到END_DATE的前一天,和你给出的期望输出一致)
WITH RECURSIVE TMP_FISCAL_DAY (FISCAL_DAY, ACTUAL_DATE, BEGIN_DATE, END_DATE, FISCAL_MONTH, FISCAL_QUARTER, FISCAL_YEAR) AS ( -- 锚点成员:初始化第一天 SELECT CAST(1 AS INT) AS FISCAL_DAY, BEGIN_DATE AS ACTUAL_DATE, BEGIN_DATE, END_DATE, FISCAL_MONTH, FISCAL_QUARTER, FISCAL_YEAR FROM DB_NAME.ORIGINAL_FISCAL_TABLE UNION ALL -- 递归成员:每天递增 SELECT Fiscal_Day + 1, ACTUAL_DATE + INTERVAL '1 day', -- 不同数据库语法可能略有差异,比如Snowflake用ACTUAL_DATE + 1 BEGIN_DATE, END_DATE, FISCAL_MONTH, FISCAL_QUARTER, FISCAL_YEAR FROM TMP_FISCAL_DAY WHERE ACTUAL_DATE < END_DATE -- 终止条件:直到Actual Date到达END_DATE的前一天 ) SELECT * FROM TMP_FISCAL_DAY;
注意事项
- 日期加法的语法可能因数据库不同而调整:
- PostgreSQL:
ACTUAL_DATE + INTERVAL '1 day' - Snowflake:
ACTUAL_DATE + 1 - SQL Server:
DATEADD(day, 1, ACTUAL_DATE)
- PostgreSQL:
- 如果你需要
Actual Date包含END_DATE,可以把终止条件改为ACTUAL_DATE <= END_DATE,同时Fiscal Day会多1天(对应END_DATE)
验证输出
运行这个查询后,你会得到和期望一致的结果:
| FISCAL_DAY | Actual Date | BEGIN_DATE | END_DATE | FISCAL_MONTH | FISCAL_QUARTER | FISCAL_YEAR |
|---|---|---|---|---|---|---|
| 1 | 12/30/2017 | 12/30/2017 | 02/02/2018 | 12 | 4 | 2018 |
| 2 | 12/31/2017 | 12/30/2017 | 02/02/2018 | 12 | 4 | 2018 |
| ... | ... | ... | ... | ... | ... | ... |
| 34 | 02/01/2018 | 12/30/2017 | 02/02/2018 | 12 | 4 | 2018 |
内容的提问来源于stack exchange,提问作者Pirate X
相关产品推荐
相关产品推荐

