如何在MySQL中查询当前时间之后的日程及重复日程记录?
解决MySQL查询重复/非重复时段未来记录的问题
首先明确表字段的含义(基于你的查询语句推测):
week:时段所在的周数(对应MySQLWEEK()函数返回值)day:时段在周内的天数(需注意是DAYOFWEEK()(1=周日)还是WEEKDAY()(0=周一)的取值)hour:时段的小时数(24小时制)recurring:1表示每周重复,0表示仅单次生效
原查询的问题在于:单独比较week、day、hour会忽略跨天/跨周但在本月内的未来事件,比如本周四的事件即使小时早于当前时间,只要日期在今天之后就应该被查到;同时重复事件的逻辑未结合本月范围限制。
改进后的查询语句
SELECT * FROM `timetable` WHERE -- 非重复事件:本月内的未来时段 ( `recurring` = 0 AND MONTH(STR_TO_DATE(CONCAT(YEAR(CURDATE()), 'W', LPAD(`week`, 2, '0'), `day`), '%YW%u%w')) = MONTH(CURDATE()) AND STR_TO_DATE(CONCAT(YEAR(CURDATE()), 'W', LPAD(`week`, 2, '0'), `day`, ' ', `hour`), '%YW%u%w %H') >= NOW() ) OR -- 重复事件:本月内存在未来的重复时段 ( `recurring` = 1 AND EXISTS ( SELECT 1 FROM ( -- 生成本月内所有该重复事件的可能日期 SELECT DATE_ADD( DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL (`day` - WEEKDAY(CURDATE())) + (n * 7) DAY ) AS event_date FROM (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS weeks ) AS future_dates WHERE MONTH(event_date) = MONTH(CURDATE()) AND CONCAT(event_date, ' ', `hour`, ':00:00') >= NOW() ) ) ORDER BY -- 按最近的未来时间排序 CASE WHEN `recurring` = 0 THEN STR_TO_DATE(CONCAT(YEAR(CURDATE()), 'W', LPAD(`week`, 2, '0'), `day`, ' ', `hour`), '%YW%u%w %H') ELSE ( SELECT MIN(CONCAT(event_date, ' ', `hour`, ':00:00')) FROM ( SELECT DATE_ADD( DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL (`day` - WEEKDAY(CURDATE())) + (n * 7) DAY ) AS event_date FROM (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) AS weeks ) AS future_dates WHERE MONTH(event_date) = MONTH(CURDATE()) AND CONCAT(event_date, ' ', `hour`, ':00:00') >= NOW() ) END ASC LIMIT 3;
逻辑说明
- 非重复事件处理:
- 用
STR_TO_DATE将year、week、day、hour拼接成完整时间,判断是否在本月内且晚于当前时间
- 用
- 重复事件处理:
- 生成本月内所有可能的重复日期(最多覆盖4周,满足一个月的周次范围)
- 检查这些日期中是否存在晚于当前时间的记录,只要有一条符合就保留该重复事件
- 排序优化:
- 统一按最近的未来时间升序排列,确保返回的3条记录是最早发生的
注意事项
- 若
day字段是DAYOFWEEK()(1=周日)的取值,需将WEEKDAY()替换为DAYOFWEEK()并调整差值计算 - 禁止直接拼接PHP变量到SQL中,务必使用参数化查询防止SQL注入
- 若
week是ISO周数,需用WEEK(CURDATE(), 3)匹配,保证周数计算逻辑一致
内容的提问来源于stack exchange,提问作者Jake Bamford
相关产品推荐
相关产品推荐

