2017-02-15 51 views
1

У меня есть таблица, которая выглядит следующим образом:Redshift - Расчет ежемесячных активных пользователей

Date  | User_ID 
2017-1-1 | 1 
2017-1-1 | 2 
2017-1-1 | 4 
2017-1-2 | 3 
2017-1-2 | 2 
...  | .. 
...  | .. 
...  | .. 
...  | .. 
2017-2-1 | 1 
2017-2-2 | 2 
...  | .. 
...  | .. 
...  | .. 

я хотел бы вычислить активных пользователей ежемесячно в течение качению период 30 дней. Я знаю, что Redshift не делает окна COUNT (DISTINCT)). Что я могу сделать, чтобы получить следующий результат?

Date  | MAU 
2017-1-1 | 3 
2017-1-2 | 4 <- We don't want to count user_id 2 twice. 
...  | .. 
...  | .. 
...  | .. 
2017-2-1 | .. 
2017-2-2 | .. 
...  | .. 
...  | .. 

Я попытался сделать это (и явно потерпел неудачу). Вот мой код:

SELECT event_date 
    ,sum(user_count) mau_count 
    ,CASE 
     WHEN event_date = date_trunc('week', event_date) 
      THEN 1 
     ELSE 0 
     END week_starting FROM (
    SELECT event_date 
     ,count(*) OVER (PARTITION BY event_date ORDER BY event_date ROWS BETWEEN 30 PRECEDING 
        AND CURRENT ROW 
      ) AS user_count <-- I know this is wrong. Just my attempt :) 
    FROM (
     SELECT DISTINCT (user_id) 
      ,event_date 
     FROM event_table 
     ) daily_distinct_users 
    GROUP BY event_date 
    ) cumulative_daily_distinct_users GROUP BY event_date; 

Пожалуйста, дайте мне знать, как я могу точно подсчитать количество MAU. Благодаря!

+0

могут отсутствовать даты? и если да, то как это следует обрабатывать? –

+0

Нет пропущенных дат, так как мы получаем хотя бы одно событие в день, если не больше. Хотя обычно больше :) – CodingInCircles

ответ

1

Это один, кажется, работает (имена столбцов в log таблице dt и userid):

SELECT 
    end_date, 
    -- The number of distinct users during the 30 days prior 
    COUNT(DISTINCT userid) distinct_users 
FROM log 
JOIN 
(-- A list of dates to appear in the output first column 
    SELECT DISTINCT dt AS end_date 
    FROM log 
    WHERE dt BETWEEN date '2017-01-01' AND date '2017-01-31' 
) ON dt BETWEEN end_date - interval '30 days' AND end_date 
GROUP BY end_date 
ORDER BY end_date 

В основном, к югу выберите генерирует список end_dates, которые появляются как первый выходной столбец. Затем он соединяется с отдельным номером userid, который появляется в течение 30 дней до выбранной даты.

+0

Работал отлично в первый раз. Немного времени занял, но работал до совершенства. Благодаря! :) – CodingInCircles

+0

Вероятно, он будет работать быстрее, если столбец 'date' - ваш' SORTKEY'. –

+0

«SORTKEY» установлен в столбец «date» в базовой таблице.Это занимает около 20 минут в течение примерно 4 месяцев. Вероятно, у меня должен быть промежуточный стол, чтобы ускорить процесс. – CodingInCircles

1

Предполагая, что не будет отсутствующих дат, вы можете сначала получить первое свидание с пользователем, используя функцию MIN. Затем получите счетчик пользователей для каждой даты, а затем используйте функцию SUM, чтобы получить текущую сумму.

SELECT DISTINCT EVENT_DATE, 
SUM(CNT) OVER(ORDER BY EVENT_DATE ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) AS MAU 
FROM 
(SELECT E.EVENT_DATE, 
     COUNT(DISTINCT T.USER_ID) AS CNT 
    FROM EVENT_TABLE E 
    LEFT JOIN 
    (SELECT DISTINCT USER_ID, 
    MIN(EVENT_DATE) OVER(PARTITION BY USER_ID 
          ORDER BY EVENT_DATE ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) AS FIRST_APPEARED_ON 
    FROM EVENT_TABLE 
    ) T ON T.FIRST_APPEARED_ON=E.EVENT_DATE AND T.USER_ID=E.USER_ID 
    GROUP BY E.EVENT_DATE 
) T1 

Sample Demo using SQL Server

+0

Это не делает его отличным, хотя. Мы ожидаем увидеть MAU в 100k. С этим запросом он находится в миллионах. Результаты на самом деле похожи на предыдущую итерацию моего запроса. – CodingInCircles

+0

Посмотрите, работает ли редактирование, как ожидалось. –

+0

Я пробовал это, и он не работал в Redshift. Что-то не в том, что невозможно разрешить e.user_id в условии соединения. Глядя на код, я вижу, что он будет работать (и демо тоже помогло!). Я снова ударю на него позже, но на данный момент, принимая ответ @John Rotenstein, поскольку он работал с очень минимальными изменениями. Спасибо за ваш ответ. – CodingInCircles

0

@ Ответ Джона Ротенштейна работает хорошо.

Для тех, кто наткнулся на этот вопрос и ищет что-то немного больше, следующее blog post описывает альтернативную стратегию предвычисления для быстрого вычисления подвижных МАУ. Это избыточно для вопроса здесь, но может пригодиться в случае, если:

  • является раздраженным с медленной скоростью роста метрических вычислений для интерактивных запросов,
  • нужно вычислить другие метрики качения роста (например, регистрацию, активация, удержание, реактивация), или
  • регулярно выполняют анализы, которые включают в себя некоторый тип числа опрошенных пользователей.