postgres:使用特定于每个组条件的条件运行group by?

时间:2018-09-06 16:43:52

标签: postgresql

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

 id                            | integer                     |           | not null | nextval('user_id_seq'::regclass)
 name                          | character varying           |           | not null | 
 t_registered       | timestamp without time zone |           | not null |  

我有一个action表:

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

我想要一种用整数字段num_days注释每个用户的方法,该字段指示在用户注册后的30天内有多少不同的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;

但是我在如何针对每个用户的30天时间窗口中获取此限制。

我怀疑这是高级SQL!

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

2 个答案:

答案 0 :(得分:0)

SELECT actioned_by, COUNT(*)
FROM (
        SELECT actioned_by, date_trunc('day', t_actioned)
        FROM history
        JOIN user ON id = actioned_by
        WHERE t_actioned BETWEEN t_registered AND t_registered + interval '30 days'
        GROUP BY actioned_by, date_trunc('day', t_actioned)
) sub
GROUP BY actioned_by

所以首先,您说您想获得一个不同天的计数,因此您必须对date_trunc分组,否则您将在同一天(如果存在)对多个事件进行计数。

此查询的作用是,加入user以获取每个用户的注册时间戳,确保t_actioned在注册后30天内,然后按用户和唯一日期分组,最后每位用户计数。

如果要包括不执行任何操作的用户,则可以对其进行一些更改:从用户表中选择,并保留联接历史记录:

SELECT id, COUNT(*)
FROM (
        SELECT id, date_trunc('day', t_actioned)
        FROM user
        LEFT JOIN history
            ON id = actioned_by
            AND t_actioned BETWEEN t_registered AND t_registered + interval '30 days'
        GROUP BY id, date_trunc('day', t_actioned)
) sub
GROUP BY id

答案 1 :(得分:0)

您可以将COUNTFILTER表达式一起使用:

SELECT 
    u.id,
    u."name",
    COUNT(*) FILTER (WHERE h.t_actioned BETWEEN u.t_registered AND u.t_registered + INTERVAL'30 days')
FROM 
    history h
    JOIN "user" u ON u.id = h.actioned_by
GROUP BY
    u.id,
    u."name"

更多信息here