如何针对滚动1小时窗口汇总结果

时间:2019-05-23 12:53:37

标签: sql postgresql

我有一个Postgres表,其中包含到达某个位置的车辆的交付记录。 (每次旅程都有一个唯一的记录)。我可以通过使用类似这样的小时汇总来监视繁忙时段...

select count(*), LOCATION, date_trunc('hour',ARRIVALTIME)
from ARRIVALS
group by LOCATION, date_trunc('hour',ARRIVALTIME)
order by LOCATION, date_trunc('hour',ARRIVALTIME) desc

我可以使用它(带有较小的mod)在每个位置找到最繁忙的1小时时段。但是,这是有局限性的,它只能按完整的时间顺序进行汇总,即在1点至2点之间,然后是2点至3点之间,等等。

问题-如何找到一天中最繁忙的60分钟“滚动窗口”?

以这个为例。如果我在13:30到14:30之间每两分钟有一次到达(没有其他时间),那么上面显示的查询将告诉我,从1到2的时间段有15次送货,从2到3的时间段也是如此。我真正想要的是一个查询,该查询将告诉我我最忙的60分钟是13:30和14:30之间的30交货。

我正在使用Postgres 10.5版

DROP TABLE arrival;
CREATE TABLE arrival (  location CHAR(15),  arrivalTime TIMESTAMP);
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 09:45:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 09:50:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 09:55:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 09:59:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 10:10:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 10:15:00');
INSERT INTO arrival (location,arrivalTime) VALUES('LONDON','01-Jan-2000 10:25:00');
INSERT INTO arrival (location,arrivalTime) VALUES('PARIS','01-Jan-2000 09:58:00');
INSERT INTO arrival (location,arrivalTime) VALUES('PARIS','01-Jan-2000 10:01:00');
INSERT INTO arrival (location,arrivalTime) VALUES('PARIS','01-Jan-2000 10:02:00');
INSERT INTO arrival (location,arrivalTime) VALUES('PARIS','01-Jan-2000 11:02:00');

到目前为止,这两个建议都表明“ RANGE FOLLOWING仅受UNBOUNDED支持”这两个错误。 “ RANGE”对我来说是陌生的,所以我目前正在阅读。

更新-好的,看来'RANGE'需要版本11。有人知道是否有解决方法吗?

2 个答案:

答案 0 :(得分:3)

您可以将窗口功能与range窗口说明符一起使用:

select a.*,
       count(*) over (order by arrivaltime
                      range between current row and '1 hour'::interval following
                     ) as hourcnt
from arrivals a
order by hourcnt desc
fetch first 1 row only;

答案 1 :(得分:1)

对于Postgres 11来说,它可以工作(因为我没有用于测试的示例数据只是一个草图)

SELECT
    COUNT(*) OVER (ORDER BY arrivaltime RANGE BETWEEN interval '30 minutes' PRECEDING AND interval '30 minutes' FOLLOWING)
FROM
    arrival
ORDER BY count DESC

RANGE window function对每条有序记录的计数都在前后30分钟带有时间戳的所有记录中进行。当然,可以对其进行调整以更好地适合您的用例(也许BETWEEN CURRENT ROW AND interval '1 hour' FOLLOWING

Further reading