SQL Server中利用函数生成半月度摊销计划到期日
解决半月度摊销计划的到期日填充问题
你的duedategenerator函数逻辑完全没问题,能够正确处理半月度的到期日规则(每月15日/月末,二月特殊处理月末)。不过你之前尝试的LAG窗口函数方式无法实现递推生成——因为LAG只能取结果集中已有的上一行数据,而后续NULL行的到期日需要依赖前一期已生成的正确日期,这里用递归CTE是更合适的方案。
步骤1:确保你的函数已正确创建
如果还没创建duedategenerator函数,先执行这段代码:
CREATE FUNCTION dbo.duedategenerator(@dt DATE) RETURNS DATE AS BEGIN RETURN CASE WHEN DAY(@dt) < 16 THEN CASE WHEN MONTH(@dt) = 2 THEN EOMONTH(@dt) ELSE DATEADD(DAY, 30 - DAY(@dt), @dt) END ELSE DATEADD(MONTH, 1, DATEADD(DAY, 15 - DAY(@dt), @dt)) END END
步骤2:用递归CTE生成完整到期日计划
递归CTE会从第一期的已知到期日开始,逐期递推生成后续每一期的到期日:
WITH RecursiveInstallments AS ( -- 锚点:取第一期的已有数据 SELECT instno, amount, duedate FROM YourTableName -- 替换成你的实际表名 WHERE instno = 1 UNION ALL -- 递归:基于上一期的到期日生成当前期的到期日 SELECT t.instno, t.amount, dbo.duedategenerator(r.duedate) AS duedate FROM YourTableName t JOIN RecursiveInstallments r ON t.instno = r.instno + 1 WHERE t.duedate IS NULL ) SELECT * FROM RecursiveInstallments ORDER BY instno;
运行结果
执行后会得到你期望的输出:
instno | amount | duedate ------------------------------ 1 | 1000.00 | 2020-01-30 2 | 1000.00 | 2020-02-15 3 | 1000.00 | 2020-02-29 4 | 1000.00 | 2020-03-15 5 | 1000.00 | 2020-03-30
补充说明
- 递归CTE的核心是逐期依赖:每一期的到期日都由前一期的结果计算而来,完美适配你的半月度摊销规则;
EOMONTH函数会自动处理闰年二月的月末日期(比如2020年二月返回29日),无需额外判断;- 如果你的分期编号不是连续的1、2、3...,可以调整递归连接的条件(比如用
ROW_NUMBER()生成连续序号)。
内容的提问来源于stack exchange,提问作者Dekso
相关产品推荐
相关产品推荐

