按时间间隔对事件进行分组和计数,以及运行总计

时间:2014-02-26 23:05:04

标签: sql postgresql loops aggregate-functions window-functions

我是一个相当新的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

我的直觉是用子查询攻击它,但环顾四周似乎有一个建议,循环可能是要走的路。

无论哪种方式,我都不在自己的深处,正在朝着正确的方向努力。

修改

基于我在输入此内容时出现的请求的补充问题。上面的一个变体将逐月显示累计总数(尽管我想我可以自己解决这个问题)在上述方法的基础上 - 我只是添加了这个,以防它与方法相关。)

2 个答案:

答案 0 :(得分:3)

我会使用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

  • 窗口函数在聚合函数之后执行,因此我们可以在同一查询级别的聚合函数上运行窗口函数。另一个例子:
    Postgres window function and group by exception

  • 窗口函数和GROUP BY子句必须重复我们分组的基本表达式:date_trunc('month', period_start)

答案 1 :(得分:2)

如果我理解正确,您只想GROUP BY表格中的年份和月份,对于action create_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; 的每一行:

{{1}}

SQL Fiddle