postgres:特定于行的24小时周期分组吗?

时间:2018-09-06 14:57:51

标签: postgresql group-by

我正在运行Postgres 9.6。我有一个用户表:

 id                            | integer                     |           | not null | nextval('user_id_seq'::regclass)
 name                          | character varying           |           | not null | 

我有一个history表:

 actioned_by      | integer                     |           |          | 
 category         | character varying           |           | not null | 
 t_actioned       | timestamp without time zone |           | not null |     

我想要一种用整数字段num_days注释每个用户的方法,该字段指示他们在24小时内有多少不同的动作。

我知道如何获取每个用户活跃的不同日历天的计数:

 SELECT d.actioned_by, COUNT(*) AS cnt FROM 
  (SELECT date_trunc('day', t_actioned) AS day, actioned_by 
   FROM history 
   GROUP BY day, actioned_by) d 
 GROUP BY actioned_by
 ORDER BY cnt DESC;

但是有没有一种方法可以测量从第一次采取行动之时起的时间段,以允许在五分钟内登录到午夜并在十分钟后离开的人?

出于分析目的,我偶尔会运行它,因此它的运行速度是否慢并不重要。

1 个答案:

答案 0 :(得分:0)

db<>fiddle

SELECT 
    *, 
    trunc(                                                           -- E
        extract(epoch FROM (                                         -- C
            t_actioned -                                             -- B
            first_value(t_actioned) OVER (PARTITION BY actioned_by ORDER BY t_actioned)  -- A
         )) / 60 / 60 / 24                                           -- D
    ) + 1 as num_days                                                -- F
FROM history 

A:使用窗口函数first_value https://www.postgresql.org/docs/current/static/tutorial-window.html

为每个用户获取第一个时间戳

B:获取行的当前时间戳与用户的第一个时间戳之间的差异。结果是一个间隔

C:将间隔转换为秒

D:将秒转换为天

E:四舍五入到整天(减少数字)

F:添加1是因为您不希望天数的差异(一天中的2个时间戳产生的天数== 0)而是天数

测试数据:

actioned_by  t_actioned           
-----------  -------------------  
1            2018-09-08 23:55:00  
1            2018-09-09 00:10:00  
1            2018-09-10 00:05:00  
1            2018-09-10 00:15:00  
2            2018-09-09 20:15:00  
2            2018-09-10 02:15:00  
2            2018-09-10 08:15:00  
2            2018-09-10 14:15:00  
2            2018-09-10 20:14:00 

结果:

actioned_by  t_actioned           num_days  
-----------  -------------------  --------  
1            2018-09-08 23:55:00  1.0       
1            2018-09-09 00:10:00  1.0       
1            2018-09-10 00:05:00  2.0       
1            2018-09-10 00:15:00  2.0       
2            2018-09-09 20:15:00  1.0       
2            2018-09-10 02:15:00  1.0       
2            2018-09-10 08:15:00  1.0       
2            2018-09-10 14:15:00  1.0       
2            2018-09-10 20:14:00  1.0