有没有办法在SQL中找到活动用户?

时间:2019-02-11 11:02:52

标签: sql postgresql

我正在尝试查找数据库中活动用户的总数。此处的“活动”用户定义为在所选日期或所选日期之后注册事件的用户。因此,如果用户在第1天,第2天和第5天注册了事件,则他们在第1天,第2天,第3天,第4天和第5天被视为“活动”。

我的原始数据集如下所示(请注意,这是一个示例-实际的数据集将运行长达365天,并具有约1000个用户)。

Day    ID
0      1
0      2
0      3
0      4
0      5
1      1
1      2
2      1
3      1
4      1
4      2

如您所见,所有5个ID在0天都处于活动状态,而2个ID(12)在4天之前都处于活动状态,因此我d像完成表一样:

Day    Count
0      5
1      2
2      2
3      2
4      2

我尝试使用以下查询:

select Day as days, sum(case when Day <= days then 1 else 0 end)
from df

但是它给出的输出不正确(仅统计每隔几天的活跃用户)。

我不知道下一步该怎么做。有人有什么想法吗?提前非常感谢!

3 个答案:

答案 0 :(得分:1)

我想我只会使用generate_series()

select gs.d, count(*)
from (select id, min(day) as min_day, max(day) as max_day
      from t
      group by id
     ) t cross join lateral
     generate_series(t.min_day, .max_day, 1) gs(d)
group by gs.d
order by gs.d;

如果您希望从第一天起就将每个人都视为活跃用户-但并非所有人在第一天都具有值-那么请使用1代替min_day。 / p>

Here是db <>小提琴。

答案 1 :(得分:0)

有点冗长,但这应该可以做到:

with dt as (
        select 0 d, 1 id
        union all
        select 0 d, 2 id
        union all
        select 0 d, 3 id
        union all
        select 0 d, 4 id
        union all
        select 0 d, 5 id
        union all
        select 1 d, 1 id
        union all
        select 1 d, 2 id
        union all
        select 2 d, 1 id
        union all
        select 3 d, 1 id
        union all
        select 4 d, 1 id
        union all
        select 4 d, 2 id
)
, active_periods as (
        select id
                , min(d) min_d
                , max(d) max_d
        from dt
        group by id
)
, days as (
        select distinct d
        from dt
)
select d.d
        , count(ap.id)
from days d
join active_periods ap on d.d between ap.min_d and ap.max_d
group by 1
order by 1 asc

答案 2 :(得分:0)

您需要按天计数。

select
    id,
    count(*)
from df
GROUP BY
    id
相关问题