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

Итак, у меня есть таблица visit_log, которая по сути отслеживает несколько user_visit в приложении. В столбце есть user_id и timestamp. Мне удалось агрегировать данные user_visit, например, теперь я знаю, сколько недель, двух недель, месяцев, квартала и года пользователь посетил приложение, используя следующие logi c:

SELECT DISTINCT ,user_id
                ,count( distinct date_part('year', timestamp) * 100 + date_part('week', timestamp)) as week
                ,count( distinct date_part('year', timestamp) * 100 + ceiling(date_part('week', timestamp)::decimal/2)) as biweek
                ,count( distinct date_part('year', timestamp) * 100 + date_part('month', timestamp)) as month
                ,count( distinct date_part('year', timestamp) * 100 + ceiling(date_part('month', timestamp)::decimal/3)) as quarter
                ,count( distinct date_part('year', timestamp)) as year
     FROM visit_logs

Now Я хочу сделать еще один шаг и определить пользователей как еженедельных, двухнедельных, ежемесячных, ежеквартальных, ежегодных и редко возвращающихся пользователей, чтобы они следовали 80% порогового значения по всем сегментам, чтобы уточнить, возвращается ли пользователь в приложение больше чем 80% времени в течение недели в выбранном временном диапазоне, тогда он является еженедельным пользователем и т. д.

Ниже приведен код SQL, который я попытался сделать еще на один шаг дальше и воспроизвести вышеизложенное Python logi c:

, temp AS 
(
      SELECT 
              user_id
              ,SUM(week) * 0.8 as total_weeks
              ,SUM(biweek) * 0.8 as total_biweek
              ,SUM(month) * 0.8 as total_months
              ,SUM(quarter) * 0.8 as total_quarters
              ,SUM(year) * 0.8 as total_year
      FROM  time_count
      GROUP BY 1
)


,week_count as 
(
            SELECT CASE WHEN week > total_weeks THEN 'Weekly'
                        WHEN biweek > total_biweek  THEN 'Biweekly'
                        WHEN month > total_months THEN 'Monthly'
                        WHEN quarter > total_quarters THEN 'quarterly'
                        WHEN year > total_year THEN 'yearly'
                        ELSE 'rarely' 
                    END as time_bucket
            FROM time_count
            LEFT JOIN temp ON temp.user_id = time_count.user_id
                           
)

SELECT * FROM week_count

Не уверен, где я ошибаюсь, но похоже, что это работает не так, как ожидалось. Пожалуйста, сообщите / помогите при первой возможности

1 Ответ

0 голосов
/ 06 августа 2020

Я немного сбит с толку. Я бы подошел к этому с помощью оконных функций. Вот пример со встроенными тайм-фреймами:

select user_id,
       (case when num_weeks > 0.8 * total_weeks then 'weekly'
             when num_months > 0.8 * total_months then 'monthly'
             when num_years > 0.8 * total_years then 'yearly'
             else 'rarely'
        end) as frequency
from (select user_id,
             count(distinct date_trunc('week', timestamp)) as num_weeks,
             count(distinct date_trunc('month', timestamp)) as num_months,
             count(distinct date_trunc('year', timestamp)) as num_years,
             extract(day from current_date - min(timestamp)) / 7 as total_weeks,
             extract(year from age(min(timestamp, current_date))) * 12 + extract(month from age(min(timestamp, current_date))) as total_months,
             extract(year from age(min(timestamp, current_date))) as total_years
      from visit_logs vl
      group by user_id
     ) vl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...