如何在 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_truncgrid 可能会对此有所帮助,但我真的不确定如何解决这个问题。有什么建议吗?

【问题讨论】:

五分钟的时间间隔可以固定在任何地方,所以您希望它从整点开始还是其他起点? 任意起点是我的目标 【参考方案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 中按时间间隔聚合行数?的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle SQL 中按时间间隔聚合数据

在 PostgreSQL 的窗口函数中按降序聚合排序

选择行数,按 PostgreSQL 中时间间隔的动态范围排序

如何安排python脚本在aws中按预定时间间隔运行

在oracle中按要求统计行数,怎么运用sum和count函数?

如何在mongodb聚合中按顺序获取计数?