【问题标题】:How to count Returning users如何计算回访用户
【发布时间】:2020-03-13 07:57:31
【问题描述】:

我正在学习 SQL。现在我有一个包含列的表:user_id、event_timestamp 和 event_name。我需要统计每个月的新用户 (I) 和第二个月返回站点的用户 (II)(例如,如果用户第一次出现是在 2 月份,他们在 3 月份使用该站点,则应该统计他们。我想我计算了第一列(I),但我不知道如何计算第二列。 因此,结果应该有一个包含“月和年”、“每月新用户”和“returning_users”列的表。

select
    distinct date_trunc('month', u.date_timestamp) as month_and_year,
    count(*) as count_users
from (select distinct on (t.user_id) *
    from example_table.table as t
    order by t.user_id, t.date_timestamp
 ) as u
group by month_and_year
order by month_and_year

所以,答案中的解决方案有效,但我仍然有问题。我不确定,但我认为它并不像我想要的那样工作。我在这样的真实基础上尝试过:

select date_trunc('month', u.ship_date) as month_and_year,
       count(distinct case when date_trunc('month', u.ship_date) = date_trunc('month', u.min_date) then cust_id end) as num_starts,
       count(distinct case when date_trunc('month', u.ship_date) = date_trunc('month', u.min_date + interval '1 month') then cust_id end) as num_returning
from (select sh.*,
             min(ship_date) over (partition by cust_id) as min_date
      from shipping.shipment as sh
     ) u

group by month_and_year
order by month_and_year

我有一张这样的桌子:

+----------------------------+------------+---------------+
| month_and_year             | num_starts | num_returning |
+----------------------------+------------+---------------+
| January 1, 2016, 12:00 AM  | 6          | 0             |
+----------------------------+------------+---------------+
| February 1, 2016, 12:00 AM | 8          | 1             |
+----------------------------+------------+---------------+
| March 1, 2016, 12:00 AM    | 16         | 0             |
+----------------------------+------------+---------------+
| April 1, 2016, 12:00 AM    | 29         | 1             |
+----------------------------+------------+---------------+
| May 1, 2016, 12:00 AM      | 23         | 9             |
+----------------------------+------------+---------------+
| June 1, 2016, 12:00 AM     | 13         | 10            |
+----------------------------+------------+---------------+
| July 1, 2016, 12:00 AM     | 4          | 5             |
+----------------------------+------------+---------------+
| August 1, 2016, 12:00 AM   | 0          | 2             |
+----------------------------+------------+---------------+

如您所见,看起来 7 月和 8 月返回的用户比刚出现的用户多。那是因为这个查询显示谁在本月返回,但我想知道,例如,在 2 月出现的有多少人在 个月返回(所以, f.e. 三月)。我想现在第二个数字在 num_returning 的下面一行。你能帮我做对吗?

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。

标签: sql postgresql


【解决方案1】:

使用窗口函数引入第一个月。然后使用条件聚合:

select date_trunc('month', u.date_timestamp) as month_and_year,
       count(distinct case when date_trunc('month', u.date_timestamp) = date_trunc('month', u.dt) then user_id end) as num_starts,
       count(distinct case when date_trunc('month', u.date_timestamp) > date_trunc('month', u.dt) then user_id end) as num_returning
    count(*) as count_users
from (select t.*,
             min(u.date_timestamp) over (partition by user_id) as min_dt
      from example_table.table as t
     ) u
group by month_and_year
order by month_and_year;

其实我觉得在子查询中将数据减少到每个用户每月一行会更有效率:

select yyyymm,
       count(*) filter (where yyyymm = min_yyyymm) as num_starts,
       count(*) filter (where yyyymm > min_yyyymm) as num_returns
from (select distinct on (user_id, date_trunc('month', u.date_timestamp)),
             t.*,
             date_trunc('month', u.date_timestamp) as yyyymm,
             min(date_trunc('month', u.date_timestamp)) over (partition by user_id) as min_yyyymm
      from example_table.table as t
      order by user_id, date_trunc('month', u.dt), u.dt
     ) u
group by yyyymm
order by yyyymm;

编辑:

如果你想要他们开始后一个月返回的数字,你也可以添加它:

select yyyymm,
       count(*) filter (where yyyymm = min_yyyymm) as num_starts,
       count(*) filter (where yyyymm > min_yyyymm) as num_returns,
       count(*) filter (where yyyymm = min_yyyymm + interval '1 month') as num_returns_second_month

【讨论】:

  • 非常感谢!但是我还有一个问题,我在主帖中添加了更多信息,你能再帮我一次吗?
猜你喜欢
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多