SQLite3(pandasql)按version分组生成两日期列间连续日期列表
问题背景
- 待处理数据集为
df,包含version、date_from、date_to三个字段,样例数据:- ver1关联两组日期区间:2020-01-052020-01-07、2022-02-052022-02-07
- ver2关联一组日期区间:2021-05-09~2021-05-11
- 目标:按
version维度,将每个日期区间展开为包含起止日期在内的连续逐天明细,最终输出version、date两个字段,共9条记录。 - 原有递归CTE代码运行失败,原代码如下:
WITH RECURSIVE dates(Date) AS ( SELECT date_from from df as Date UNION ALL SELECT date(date, '+1 day') FROM dates WHERE Date < (Select date_to from df) ) SELECT DATE(Date) FROM dates;
原代码问题点
- 递归初始化阶段未同步携带
version字段和当前区间对应的date_to边界值,递归过程无法关联所属版本,也无法匹配对应区间的截止日期 - 终止条件中
(Select date_to from df)会返回表中所有的date_to值(共3个),无法和当前递归的日期行做匹配,会直接触发执行错误 - 最终查询未返回
version字段,不满足输出字段要求
修正后代码
以下是适用于MySQL 8.0+、SQLite的标准递归CTE写法:
WITH RECURSIVE date_expand AS ( -- 递归锚点:读取所有日期区间的起始值,携带版本和截止日期边界 SELECT version, date_from AS date, date_to FROM df UNION ALL -- 递归逻辑:当前日期逐天加1,直到触达当前区间的截止日期即停止 SELECT version, DATE(date, '+1 day') AS date, date_to FROM date_expand WHERE date < date_to ) -- 输出指定字段,按版本和日期排序 SELECT version, date FROM date_expand ORDER BY version, date;
执行结果
执行后将返回预期的9条明细:
- ver1:2020-01-05、2020-01-06、2020-01-07、2022-02-05、2022-02-06、2022-02-07
- ver2:2021-05-09、2021-05-10、2021-05-11
如果使用PostgreSQL,把日期加1的逻辑替换为
date + INTERVAL '1 day'即可;如果是Hive/Spark SQL,日期加1使用date_add(date, 1)。
内容的提问来源于stack exchange,提问作者Lana
相关产品推荐
相关产品推荐

