2017-03-20 15 views
1

アクションフィールドが値1に変更されるたびに、各ユーザのカウントが必要です。最初のエントリが1の場合もカウントされます。行は順不同ですが、action_dateによって順番に数えられるべきです。PostgreSQLのグループ内のウィンドウ機能

つまり、私が考える必要があるのは、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); 

結果は

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; 

、私は単一のアカウントに対する結果をこのように得ることができますthis答えからの助けを借りて

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

する必要がありますが、それを全員に拡大しようとしているers。

答えて

2

partition bylag()機能を使用します。

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; 
+0

私はこの '' 'ERRORしようとすると、私は次のエラーを取得しています:(上ラグ(アクション): "(" LINE 3構文エラーまたはその付近をuser_idでパーティションを区切ります。... '' ' – rurp

+0

その優雅な答えをありがとう、それは完全に動作します。 – rurp