SAS EG中两个给定日期间按间隔5天生成连续日期序列的实现方法
按间隔5天生成日期序列实现方案
核心实现逻辑优先采用递归CTE完成,以下为不同主流数据库的可运行代码:
MySQL 8.0+ 版本
WITH RECURSIVE date_series AS ( -- 初始节点:取每个Item的起始日期Date1 SELECT Item, Date1 AS Date, Date2 FROM Table1 UNION ALL -- 递归节点:每次日期加5天,直到不超过对应Item的Date2 SELECT Item, DATE_ADD(Date, INTERVAL 5 DAY), Date2 FROM date_series WHERE DATE_ADD(Date, INTERVAL 5 DAY) <= Date2 ) -- 输出最终结果 SELECT Item, Date FROM date_series ORDER BY Item, Date;
如果使用低于8.0不支持递归CTE的MySQL版本,可以借助预先构造的数字辅助表实现:
-- 假设存在存储0到1000的数字辅助表nums(id),覆盖最大日期间隔所需的步数 SELECT t.Item, DATE_ADD(t.Date1, INTERVAL n.id *5 DAY) AS Date FROM Table1 t JOIN nums n ON DATE_ADD(t.Date1, INTERVAL n.id *5 DAY) <= t.Date2 ORDER BY t.Item, Date;
PostgreSQL 版本
WITH RECURSIVE date_series AS ( SELECT Item, Date1::date AS Date, Date2::date FROM Table1 UNION ALL SELECT Item, Date + INTERVAL '5 days', Date2 FROM date_series WHERE Date + INTERVAL '5 days' <= Date2 ) SELECT Item, Date::date FROM date_series ORDER BY Item, Date;
也可以直接用PostgreSQL内置的generate_series函数简化实现:
SELECT t.Item, generate_series(t.Date1::date, t.Date2::date, '5 days'::interval)::date AS Date FROM Table1 t ORDER BY t.Item, Date;
SQL Server 版本
WITH RECURSIVE date_series AS ( SELECT Item, Date1 AS Date, Date2 FROM Table1 UNION ALL SELECT Item, DATEADD(DAY,5,Date), Date2 FROM date_series WHERE DATEADD(DAY,5,Date) <= Date2 ) SELECT Item, Date FROM date_series ORDER BY Item, Date OPTION (MAXRECURSION 0); -- 关闭递归层数限制,避免长日期间隔场景下结果被截断
- 注意:如果你的数据库对递归CTE的最大递归层数有默认限制,长日期间隔场景下需要调整对应参数避免结果不完整。
内容的提问来源于stack exchange,提问作者Dia
相关产品推荐
相关产品推荐

