如何在 PostgreSQL 中按时间间隔聚合行数?
Posted
技术标签:
【中文标题】如何在 PostgreSQL 中按时间间隔聚合行数?【英文标题】:How can I aggregate a count of rows by time intervals in PostgreSQL? 【发布时间】:2020-12-07 19:28:09 【问题描述】:如果我有一个 PostgreSQL 表,其中包含日期时间列和项目数组,例如:
| time | items |
| -------------------------- | ---------------------- |
| 2020-12-06 11:31:38.000 | item1, item2 |
| 2020-12-06 11:48:11.304 | item1 |
| 2020-12-06 11:48:48.654 | item1, item2, item3 |
| 2020-12-06 11:49:50.355 | item2 |
| 2020-12-06 11:55:31.842 | item1, item2 |
如何查询表以在等距时间间隔内聚合特定项目的计数?
例如,我想每隔 5 分钟统计一次item1
的出现次数,这样查询结果如下所示:
| start_time | end_time | item1 count |
| -------------------------- | ----------------------------------- | --------------- |
| 2020-12-06 11:30:00.000 | 2020-12-06 11:34:99.999 | 1 |
| 2020-12-06 11:35:00.000 | 2020-12-06 11:39:99.999 | 0 |
| 2020-12-06 11:40:00.000 | 2020-12-06 11:44:99.999 | 0 |
| 2020-12-06 11:45:00.000 | 2020-12-06 11:49:99.999 | 2 |
| 2020-12-06 11:50:00.000 | 2020-12-06 11:54:99.999 | 0 |
| 2020-12-06 11:55:00.000 | 2020-12-06 11:59:99.999 | 1 |
我很难弄清楚哪些查询可以帮助我以最佳方式实现这一目标。我一直在想 Postgres 的 date_trunc
或 grid
可能会对此有所帮助,但我真的不确定如何解决这个问题。有什么建议吗?
【问题讨论】:
五分钟的时间间隔可以固定在任何地方,所以您希望它从整点开始还是其他起点? 任意起点是我的目标 【参考方案1】:您可以使用generate_series()
来生成时间戳。然后取消嵌套、过滤和聚合:
select gs.ts, count(i.time) as num_item1
from generate_series('2020-12-06 11:30:00.000'::timestamp, '2020-12-06 11:55:00.000', interval '5 minute') gs(ts) left join
(items i join lateral
unnest(i.items) item
on item = 'item1'
)
on i.time >= gs.ts and i.time < gs.ts + interval '5 minute'
group by gs.ts
order by 1;
Here 是一个 dbfiddle。
【讨论】:
效果很好,你是个巫师!小问题:如果我需要通过一些额外的列进一步过滤我的查询,我可以简单地做类似on item = 'item1' and otherColumn = 'someValue'
的事情吗?
@user12533955 。 . .我认为这会奏效。以上是关于如何在 PostgreSQL 中按时间间隔聚合行数?的主要内容,如果未能解决你的问题,请参考以下文章
选择行数,按 PostgreSQL 中时间间隔的动态范围排序