1

我在 MySQL 中有一张表,上面有客户花费的时间,我需要找到最繁忙的 30 分钟。

CREATE TABLE Customer
   (id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    customerId int NOT NULL,
    arrival datetime,
    leaving datetime);

INSERT INTO Customer
   (customerId, arrival, leaving)
VALUES
   (1, '2018-01-01 10:00:00', '2018-01-01 12:00:00'),
   (2, '2018-01-01 11:00:00', '2018-01-01 12:00:00'),
   (3, '2018-01-01 11:30:00', '2018-01-01 12:30:00'),
   (4, '2018-01-01 13:30:00', '2018-01-01 14:30:00')
;

预期结果类似于具有时间和客户数量的多行:

   10:00    10:30    1
   10:30    11:00    1
   11:00    11:30    2
   11:30    12:00    3
   12:00    12:30    1

我可以轻松地进行 5 个 sql 查询并获得结果(我在类似问题https://stackoverflow.com/a/59478411/11078894中提出了一些看法),但我不知道如何通过 1 个查询获得结果。

请问如何在MySQL中制作子间隔?谢谢

4

2 回答 2

0

这是一个基于union all和窗口函数(在 SQL 8.0 中可用)的解决方案,可以让您非常接近:

select 
    dt start_dt,
    lead(dt) over(order by dt) end_dt, 
    sum(sum(cnt)) over(order by dt) cnt
from (
    select arrival dt, 1 cnt from Customer
    union all
    select leaving, -1 from Customer
) t
group by dt
order by dt

逻辑是在每次到达时增加一个全局计数器,并在每次离开时减少它。然后,您可以聚合并进行窗口求和。

与您的预期结果的唯一区别是此查询不会生成固定的间隔列表,而是生成客户数量恒定的间隔列表,如您在此演示中所见:

start_dt            | end_dt              | cnt
:------------------ | :------------------ | --:
2018-01-01 10:00:00 | 2018-01-01 11:00:00 |   1
2018-01-01 11:00:00 | 2018-01-01 11:30:00 |   2
2018-01-01 11:30:00 | 2018-01-01 12:00:00 |   3
2018-01-01 12:00:00 | 2018-01-02 12:30:00 |   1
2018-01-02 12:30:00 |                     |   0
于 2019-12-30T15:51:46.223 回答
0

感谢 GMB 的帖子,我也为 SQL 5 Some 视图找到了解决方案:

CREATE OR REPLACE VIEW changeTimeView AS
select arrival AS changeTime, 1 cnt from Customer
union all
select leaving, -1 from Customer
ORDER BY changeTime

创建视图后:

SELECT DISTINCT chT2.changeTime,  (SELECT SUM(chT1.cnt) FROM changeTimeView chT1 WHERE TIMEDIFF(chT1.changeTime,chT2.changeTime)<=0) FROM changeTimeView chT2

结果:

2018-01-01 10:00:00     1
2018-01-01 11:00:00     2
2018-01-01 11:30:00     3
2018-01-01 12:00:00     1
2018-01-01 12:30:00     0
2018-01-01 13:30:00     1
2018-01-01 14:30:00     0
于 2019-12-30T17:27:45.747 回答