如何提取数据表中From列与To列区间内的所有日期?
展开日期区间生成所有日期记录
刚好做过类似的需求,我来给你整理几种主流数据库下的实现方案,都能把你表里每个日期区间内的所有日期单独列出来,得到你想要的结果。
原始数据表
| Id | From | To |
|---|---|---|
| 1 | 2018-01-28 | 2018-02-01 |
| 2 | 2018-02-10 | 2018-02-12 |
| 3 | 2018-02-27 | 2018-03-01 |
期望输出
| FromDate |
|---|
| 2018-01-28 |
| 2018-01-29 |
| 2018-01-30 |
| 2018-01-31 |
| 2018-02-01 |
| 2018-02-10 |
| 2018-02-11 |
| 2018-02-12 |
| 2018-02-27 |
| 2018-02-28 |
| 2018-03-01 |
不同数据库的实现方法
1. SQL Server
用递归CTE(公共表表达式)来逐层生成日期,关联你的原始表即可:
WITH DateRange AS ( SELECT Id, [From] AS FromDate, [To] FROM YourTable -- 替换成你的实际表名 UNION ALL SELECT Id, DATEADD(DAY, 1, FromDate), [To] FROM DateRange WHERE FromDate < [To] ) SELECT FromDate FROM DateRange ORDER BY FromDate OPTION (MAXRECURSION 0); -- 解除默认的递归层数限制(默认100层,足够覆盖大多数日期区间)
2. MySQL
MySQL 8.0及以上版本(支持递归CTE)
写法和SQL Server类似,只是日期函数略有不同:
WITH RECURSIVE DateRange AS ( SELECT Id, `From` AS FromDate, `To` FROM YourTable -- 替换成你的实际表名 UNION ALL SELECT Id, DATE_ADD(FromDate, INTERVAL 1 DAY), `To` FROM DateRange WHERE FromDate < `To` ) SELECT FromDate FROM DateRange ORDER BY FromDate;
MySQL 5.x版本(无递归CTE)
可以先创建一个数字辅助表,用数字来生成日期偏移量:
-- 先创建一个临时数字表(如果已经有类似的表可以跳过这步) CREATE TEMPORARY TABLE Numbers (n INT); INSERT INTO Numbers VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -- 关联数字表生成所有日期 SELECT DATE_ADD(t.`From`, INTERVAL (a.n + b.n*10) DAY) AS FromDate FROM YourTable t JOIN Numbers a JOIN Numbers b ON (a.n + b.n*10) <= DATEDIFF(t.`To`, t.`From`) ORDER BY FromDate;
注:如果你的日期区间超过100天,可以再加一层Numbers c,用a.n + b.n*10 + c.n*100来扩展范围
3. PostgreSQL
PostgreSQL自带generate_series函数,实现起来非常简洁:
SELECT generate_series(t."From", t."To", '1 day'::interval)::date AS FromDate FROM YourTable t -- 替换成你的实际表名 ORDER BY FromDate;
内容的提问来源于stack exchange,提问作者Morteza
相关产品推荐
相关产品推荐

