MySQL中如何根据两个日期字段展开生成日期范围内的对应记录
MySQL日期范围拆分实现方案
该需求完全可以实现,核心思路是生成连续日期序列和原表关联,过滤出落在两个日期字段范围内的日期即可,以下是不同MySQL版本的实现方式:
MySQL 8.0及以上版本(支持递归CTE)
优先使用递归CTE生成日期序列,实现更灵活:
1. 模拟测试表与数据
CREATE TABLE demo ( id INT, data VARCHAR(255), datetime_1 DATETIME, datetime_2 DATETIME ); INSERT INTO demo VALUES (1, 'row data 1', '2021-06-28 10:00:00', '2021-07-02 10:00:00');
2. 查询语句
WITH RECURSIVE date_sequence AS ( SELECT DATE(datetime_1) AS date_val FROM demo UNION ALL SELECT date_val + INTERVAL 1 DAY FROM date_sequence WHERE date_val < (SELECT MAX(DATE(datetime_2)) FROM demo) ) SELECT d.id, d.data, ds.date_val AS target_date FROM demo d INNER JOIN date_sequence ds ON ds.date_val BETWEEN DATE(d.datetime_1) AND DATE(d.datetime_2);
执行后即可得到对应每条记录按日期拆分的结果,示例测试数据会返回2021-06-28到2021-07-02共5条符合要求的记录。
MySQL 5.x版本(不支持递归CTE)
可以通过数字辅助表实现:
方案A:使用预先创建的数字辅助表
提前创建包含连续数字的nums表(num字段从0开始递增,覆盖业务最大日期间隔即可):
SELECT d.id, d.data, DATE(d.datetime_1) + INTERVAL n.num DAY AS target_date FROM demo d INNER JOIN nums n ON DATE(d.datetime_1) + INTERVAL n.num DAY <= DATE(d.datetime_2);
方案B:临时构造数字序列
如果没有提前建辅助表,也可以临时构造数字序列,仅适合日期间隔较小的场景:
SELECT d.id, d.data, DATE(d.datetime_1) + INTERVAL n.num DAY AS target_date FROM demo d INNER JOIN ( SELECT 0 num UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 -- 可根据需要的间隔长度扩展更多UNION ALL ) n ON DATE(d.datetime_1) + INTERVAL n.num DAY <= DATE(d.datetime_2);
内容的提问来源于stack exchange,提问作者suryanegara
相关产品推荐
相关产品推荐

