我有一个表格,用于存储应用程序用户的活动信息。
| username | day |
|----------|-----|
| u1 | 1 |
| u1 | 2 |
| u1 | 3 |
| u2 | 2 |
| u3 | 1 |
| u3 | 4 |
我希望能够获取每天唯一和最近用户的历史数据。
我能够获取每个特定日期处于活动状态的用户列表,但我不确定如何汇总这些数据以获得唯一或最近的用户。
SELECT
day,
array_agg(username) as day_users
FROM myTable
GROUP BY day
ORDER BY day;
| day | day_users |
|-----|-----------|
| 1 | u1, u3 |
| 2 | u1,u2 |
| 3 | u1 |
| 4 | u3 |
对于上面的示例数据,预期输出将是(不需要间距):
| day | unique_users | recent_users
|-----|--------------|-------------
| 1 | u1, u3 | u1, u3
| 2 | u1,u2,u3 | u1,u2,u3
| 3 | u1,u2,u3 | u1,u2
| 4 | u1,u2,u3 | u1, u3
相关SQL小提琴:http://sqlfiddle.com/#!17/b793f/1
答案 0 :(得分:1)
您需要自定义聚合函数:
create or replace function array_union(anyarray, anyarray)
returns anyarray language sql
as $$
select
array(
select unnest($1)
union
select unnest($2)
order by unnest
)
$$;
create aggregate array_union_agg (anyarray)
(
sfunc = array_union,
stype = anyarray
);
在查询中使用聚合作为窗口函数,基于你的一个:
select
day,
day_users,
array_union_agg(day_users) over (order by day) as unique_users,
array_union_agg(day_users) over (order by day rows between 1 preceding and current row) as recent_users
from (
select day, array_agg(username) as day_users
from my_table
group by day
order by day
) s
day | day_users | unique_users | recent_users
-----+-----------+--------------+--------------
1 | {u1,u3} | {u1,u3} | {u1,u3}
2 | {u1,u2} | {u1,u2,u3} | {u1,u2,u3}
3 | {u1} | {u1,u2,u3} | {u1,u2}
4 | {u3} | {u1,u2,u3} | {u1,u3}
(4 rows)