Как считать Вернувшихся пользователей - PullRequest
0 голосов
/ 12 марта 2020

Я учусь SQL. Теперь у меня есть таблица со столбцами: user_id, event_timestamp и event_name. Мне нужно подсчитывать новых пользователей в месяц (I) и пользователей, которые вернулись на сайт во второй месяц (II) (например, если первые появления пользователей были в феврале и они использовали сайт в марте, их следует учитывать. Я думаю, что я посчитал первый столбец (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             |
+----------------------------+------------+---------------+

, как вы видите, похоже, что в июле и августе вернулось больше пользователей, чем только что появившихся. это потому, что этот запрос показывает, кто вернется в в этом месяце , но я хочу знать, сколько людей, которые появились в феврале, например, вернулись в своем следующем месяце (например, март Я думаю, что это второй номер ber находится в строке ниже в num_returning . Вы можете помочь мне сделать это правильно?

1 Ответ

0 голосов
/ 12 марта 2020

Введите первый месяц, используя оконные функции. Затем используйте условное агрегирование:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...