You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL中查询当前时间之后的日程及重复日程记录?

解决MySQL查询重复/非重复时段未来记录的问题

首先明确表字段的含义(基于你的查询语句推测):

  • week:时段所在的周数(对应MySQL WEEK() 函数返回值)
  • 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;

逻辑说明

  1. 非重复事件处理:
    • 用STR_TO_DATE将year、week、day、hour拼接成完整时间,判断是否在本月内且晚于当前时间
  2. 重复事件处理:
    • 生成本月内所有可能的重复日期(最多覆盖4周,满足一个月的周次范围)
    • 检查这些日期中是否存在晚于当前时间的记录,只要有一条符合就保留该重复事件
  3. 排序优化:
    • 统一按最近的未来时间升序排列,确保返回的3条记录是最早发生的

注意事项

  • 若day字段是DAYOFWEEK()(1=周日)的取值,需将WEEKDAY()替换为DAYOFWEEK()并调整差值计算
  • 禁止直接拼接PHP变量到SQL中,务必使用参数化查询防止SQL注入
  • 若week是ISO周数,需用WEEK(CURDATE(), 3)匹配,保证周数计算逻辑一致

内容的提问来源于stack exchange,提问作者Jake Bamford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:01:27