MySQL查询:基于起始日期与重复间隔检索指定日期区间事件
问题描述
现有如下MySQL数据表:
| ID | start | end | each_month |
|---|---|---|---|
| 1 | 2024-03-03 | 2030-01-01 | 2 |
| 2 | 2024-04-03 | 2030-01-01 | 1 |
需要编写一条查询语句,检索出落在2024-02-01至2024-07-31区间内的事件,生成如下结果集:
| ID | start |
|---|---|
| 1 | 2024-03-03 |
| 1 | 2024-05-03 |
| 1 | 2024-07-03 |
| 2 | 2024-04-03 |
| 2 | 2024-05-03 |
| 2 | 2024-06-03 |
| 2 | 2024-07-03 |
解决方案
使用MySQL 8.0及以上版本支持的递归CTE实现需求,递归生成符合间隔要求的日期后,筛选出目标区间内的记录:
WITH RECURSIVE event_dates AS ( -- 锚点成员:取原始表的初始记录 SELECT ID, start AS event_date, end, each_month FROM your_table_name WHERE start <= '2024-07-31' UNION ALL -- 递归成员:按间隔生成下一个日期 SELECT ed.ID, DATE_ADD(ed.event_date, INTERVAL ed.each_month MONTH) AS event_date, ed.end, ed.each_month FROM event_dates ed WHERE DATE_ADD(ed.event_date, INTERVAL ed.each_month MONTH) <= LEAST(ed.end, '2024-07-31') ) -- 筛选目标区间内的记录并返回 SELECT ID, event_date AS start FROM event_dates WHERE event_date >= '2024-02-01' ORDER BY ID, start;
代码说明
- 递归CTE结构:
- 锚点成员取出原始表中初始日期不晚于目标区间结束的记录,作为递归起点。
- 递归成员基于上一次生成的日期,按
each_month间隔生成新日期,直到日期超出原始表的end或目标区间结束日期。
- 边界控制:用
LEAST(ed.end, '2024-07-31')确保生成的日期同时满足原始表的结束限制和查询区间限制。 - 最终筛选:外层查询过滤掉早于目标区间起始日期的记录,保证结果完全落在指定范围内。
注意:将代码中的your_table_name替换为实际表名。
内容的提问来源于stack exchange,提问作者Luca Romano
相关产品推荐
相关产品推荐

