PostgreSQL中字段数据后几周的聚合计数

时间:2015-06-19 21:05:01

标签: postgresql aggregate

我有一个查询返回类似的内容:
registered_at - 用户注册日期;
action_at - 某种行为的日期。

|       registered_at | user_id |           action_at |
-------------------------------------------------------
| 2015-05-01 12:00:00 |       1 | 2015-05-04 12:00:00 |
| 2015-05-01 12:00:00 |       1 | 2015-05-10 12:00:00 |
| 2015-05-01 12:00:00 |       1 | 2015-05-16 12:00:00 |
| 2015-04-01 12:00:00 |       2 | 2015-04-04 12:00:00 |
| 2015-04-01 12:00:00 |       2 | 2015-04-05 12:00:00 |
| 2015-04-01 12:00:00 |       2 | 2015-04-10 12:00:00 |
| 2015-04-01 12:00:00 |       2 | 2015-04-30 12:00:00 |

我正在尝试实现将返回类似内容的查询:
weeks_after_registration - 在此示例中受限于3,在实际任务中它将受到6的限制。

| user_id |  weeks_after_registration | action_counts |
-------------------------------------------------------
|       1 |                         1 |             1 |
|       1 |                         2 |             1 |
|       1 |                         3 |             1 |
|       2 |                         1 |             2 |
|       2 |                         2 |             1 |
|       2 |                         3 |             0 |

1 个答案:

答案 0 :(得分:0)

您可以使用extract(days from (action_at - registered_at) / 7)+1获取周数。然后计算按周数分组的操作数。

  select user_id, wk, count(*) actions
  from (select user_id, extract(days from (action_at - registered_at) / 7)+1 wk from Table1) a
  where wk <= 3
  group by user_id, wk

如果必须在结果中显示action_counts = 0的行,则需要加入所有可能的周数(1,2,3)和所有可能的user_ids(1,2),如:

select b.user_id, a.wk, coalesce(c.actions, 0) actions
from (select * from generate_series(1, 3) wk) a
join (select distinct user_id from Table1) b on true
left join (
  select user_id, wk, count(*) actions
  from (select user_id, extract(days from (action_at - registered_at) / 7)+1 wk from Table1) a
  where wk <= 3
  group by user_id, wk
) c on a.wk = c.wk and b.user_id = c.user_id
order by b.user_id, a.wk;

fiddle