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

MySQL 5:如何用单查询实现工作时段最繁忙30分钟查询

单条SQL实现MySQL中找出最繁忙的30分钟时段

嗨,这个需求完全可以用单条SQL搞定!核心思路是先生成所有可能的30分钟时间区间,再统计每个区间内有多少顾客的停留时间和它重叠。下面是具体实现步骤和代码:

1. 生成30分钟时间区间

MySQL 8.0及以上支持递归CTE(WITH RECURSIVE),咱们可以用它来生成从最早到最晚停留时间范围内的所有30分钟区间:

  • 先找到所有顾客中最早的到达时间,向下取整到最近的30分钟(比如10:05就变成10:00)
  • 再找到最晚的离开时间,向上取整到最近的30分钟(比如12:20就变成12:30)
  • 然后递归生成每一个30分钟的区间,直到覆盖整个时间范围

2. 统计每个区间的顾客数

对于每个生成的30分钟区间,判断顾客的停留时间是否和它有重叠——只要顾客的到达时间早于区间结束,且离开时间晚于区间开始,就说明这个顾客在该区间内停留过。

完整SQL代码

WITH RECURSIVE time_intervals AS (
    -- 初始化:取最早的30分钟起始区间
    SELECT 
        DATE_FORMAT(DATE_SUB(arrival, INTERVAL MINUTE(arrival) % 30 MINUTE), '%Y-%m-%d %H:%i:00') AS interval_start,
        DATE_FORMAT(DATE_ADD(DATE_SUB(arrival, INTERVAL MINUTE(arrival) % 30 MINUTE), INTERVAL 30 MINUTE), '%Y-%m-%d %H:%i:00') AS interval_end
    FROM Customer
    UNION ALL
    -- 递归生成后续的30分钟区间
    SELECT 
        DATE_ADD(interval_start, INTERVAL 30 MINUTE) AS interval_start,
        DATE_ADD(interval_end, INTERVAL 30 MINUTE) AS interval_end
    FROM time_intervals
    -- 终止条件:区间开始时间不晚于最晚的离开时间(向上取整到30分钟)
    WHERE interval_start < (
        SELECT DATE_FORMAT(DATE_ADD(leaving, INTERVAL (30 - MINUTE(leaving) % 30) % 30 MINUTE), '%Y-%m-%d %H:%i:00') 
        FROM Customer 
        ORDER BY leaving DESC 
        LIMIT 1
    )
)
-- 统计每个区间的顾客数
SELECT 
    DATE_FORMAT(ti.interval_start, '%H:%i') AS start_time,
    DATE_FORMAT(ti.interval_end, '%H:%i') AS end_time,
    COUNT(DISTINCT c.customerId) AS customer_count
FROM time_intervals ti
LEFT JOIN Customer c 
    ON c.arrival < ti.interval_end 
    AND c.leaving > ti.interval_start
GROUP BY ti.interval_start, ti.interval_end
ORDER BY ti.interval_start;

代码解释

  • 递归CTE time_intervals:负责生成所有需要检查的30分钟区间,确保覆盖了所有顾客可能停留的时间段
  • 关联条件:c.arrival < ti.interval_end AND c.leaving > ti.interval_start 准确判断顾客停留时间和区间是否重叠,避免漏算或错算
  • 格式处理:用DATE_FORMAT把时间转成你需要的HH:mm格式,方便查看
  • 去重统计:用COUNT(DISTINCT c.customerId)确保同一个顾客在同一个区间只被统计一次

运行这段代码后,就能得到和你示例完全一致的结果啦!如果你的MySQL版本低于8.0,也可以用临时表或数字表来生成区间,但递归CTE是最简洁的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:03