PostgreSQL中group by中的窗口函数

Posted

技术标签:

【中文标题】PostgreSQL中group by中的窗口函数【英文标题】:Window function within group by in PostgreSQL 【发布时间】:2017-03-20 20:20:26 【问题描述】:

每次操作字段更改为值 1 时,我都需要为每个用户计数。如果第一个条目是 1,那么也可以计数。这些行是乱序的,但应该按 action_date 的顺序计算。

换句话说,我认为需要做的是:按 user_id 对行进行分组,按时间戳对它们进行排序,然后计算 action=1 和 action != 上一行的频率。

示例

create table t (
user_id int,
action_date timestamp,
action int
);

Insert into t(user_id, action_date, action)
values
(1, '2017-01-01 00:00:00', 1),
(2, '2017-01-01 00:00:00', 0),
(1, '2017-01-03 00:00:00', 1),
(2, '2017-01-03 00:00:00', 0),
(1, '2017-01-02 00:00:00', 1),
(2, '2017-01-02 00:00:00', 1),
(1, '2017-01-04 00:00:00', 1),
(2, '2017-01-04 00:00:00', 1);

结果应该是

 user_id | count 
---------+-------
       1 |     1
       2 |     2

在this答案的帮助下,我可以通过这种方式获得单个帐户的结果,

select user_id, count(*)
from (select user_id, action_date,action,lag(action) over(order by action_date) as prev_action
      from t where user_id=2
     ) t
where (action<>prev_action and action=1) or (action=1 and prev_action is null)
group by user_id;

但我一直试图将其扩展到所有用户。

【问题讨论】:

【参考方案1】:

lag() 函数与partition by 一起使用:

select user_id, count(*)
from (select t.*,
             lag(action) over (partition by user_id order by action_date) as prev_action
      from t
     ) t
where (action = 1) and (prev_action is distinct from 1)
group by user_id;

【讨论】:

当我尝试这个ERROR: syntax error at or near "(" LINE 3: lag(action) over (partition by user_id order by...时出现以下错误@ 非常感谢您的优雅回答,它完美运行。

以上是关于PostgreSQL中group by中的窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL - 必须出现在 GROUP BY 子句中或在聚合函数中使用

Postgresql 错误:列必须出现在 GROUP BY 子句中或在聚合函数中使用

Django 与 Postgresql,列必须出现在 GROUP BY 子句中或在聚合函数中使用

Postgresql“列必须出现在 GROUP BY 子句中或在聚合函数中使用”和唯一字段

Postgresql 9.2 错误与 group by 未出现在 postgresql 12 中

必须出现在 postgresql 的 GROUP BY 子句中