每个时间间隔的事件分组和计数,加上运行总数

Posted

技术标签:

【中文标题】每个时间间隔的事件分组和计数,加上运行总数【英文标题】:Group and count events per time intervals, plus running total 【发布时间】:2014-03-30 02:40:59 【问题描述】:

我是一个相当新的 Postgres 用户,我确信已经有了答案,但我找不到。 我需要分析活动日志表中的一些数据,按时间段对结果进行分组。

问题的一个简单版本是一个包含三个字段的表:

    Column    |           Type           |              Modifiers
--------------+--------------------------+-------------------------------------
 period_start | timestamp with time zone | not null
 user_id      | text                     | not null
 action       | text                     | not null

我想要捕获的操作字符串可能是“create_entry”(是的,我知道这很糟糕,但我坚持使用它)

我正在寻找的输出是按年和月显示“create_entry”操作计数的报告。比如:

 Year | Month | Entries
------+-------+----------
 2013 |  12   | 14345
 2014 |   1   | 9876
 2014 |   2   | 10234

我的直觉是用子查询来解决这个问题,但环顾四周似乎暗示循环可能是要走的路。

无论哪种方式,我都超出了我的深度,正在寻找正确方向的推动力。

编辑

根据我在输入此内容时收到的请求提出的补充问题。上面的变体将显示逐月累积的总数(尽管我想我可以自己根据关于上述方法 - 我只是添加它以防它与方法相关)。

【问题讨论】:

【参考方案1】:

使用date_trunc()时间戳截断为月份,并在单个列中涵盖年份和月份。您可以使用to_char() 以任何您喜欢的方式对其进行格式化。

要获得您在补充问题中提到的运行计数,请添加window function:

SELECT to_char(date_trunc('month', period_start), 'Mon YYYY') AS month
     , count(*) AS month_ct
     , sum(count(*)) OVER (ORDER BY date_trunc('month', period_start)) AS running_ct
FROM   activity_log
WHERE  action = 'create_entry'
GROUP  BY date_trunc('month', period_start);

sqlfiddle 用于 Psotgres 9.6dbfiddle here 用于 Postgres 12

窗口函数在聚合函数之后执行,因此我们可以在同一查询级别的聚合上运行窗口函数。相关:

Postgres window function and group by exception

必须在窗口函数和GROUP BY 中使用相同的基本表达式:date_trunc('month', period_start)

【讨论】:

【参考方案2】:

如果我理解正确,您只想GROUP BY 表中的年份和月份,对于具有actioncreate_entry 的每一行:

SELECT
  DATE_PART('YEAR', period_start) as Year,
  DATE_PART('MONTH', period_start) as Month,
  COUNT(*) as Entries
FROM activity_log
WHERE action = 'create_entry'
GROUP BY Year, Month;

SQL Fiddle

【讨论】:

这就是为什么我喜欢 *** - DATE_PART 和 date_trunc - 我以前从未见过它们 不确定它们之间是否有任何区别。 @Erwin 会知道,他比我更专业。 哦。 DATE_PART 返回一个数字(2013、2 等),DATE_TRUNC 返回一个时间戳,截断到该部分。所以,我的方式看起来更像你的示例输出。 有时我讨厌不得不选择一个首选的答案...两者都很好,都 +1。我没有资格说哪个是“最好的”,我怀疑它可能是@Erwin's 但我选择这个是因为它是我实际使用的解决方案。 @PerryW:我建议date_trunc(),偏离了您建议的结果格式,因为聚合单个列比聚合两列便宜。不过,最有趣的是运行计数,它只需要一个查询级别。

以上是关于每个时间间隔的事件分组和计数,加上运行总数的主要内容,如果未能解决你的问题,请参考以下文章

SQL按间隔分组,计数和求和

Databricks SQL - 间隔中的最大同时事件计数

分组值在 SQL (maria DB) 中按时间存储直到零,并与计数一起进行求和

分组日期之间的间隔

按序列号和天间隔分组的平均温度

如何在lua中设置事件之间的时间间隔