Как получить среднюю активность на человека в день, если нулевой день не генерирует строк / данных? - PullRequest
0 голосов
/ 24 апреля 2019

Я провожу исследование активности подписчиков на сайте. В частности, я хотел бы видеть среднее количество кликов на одного подписчика в день в 2018 году. К сожалению, предоставленная мне таблица данных не учитывает дни, когда подписчик вообще не взаимодействует с веб-сайтом, но мне нужно нулевое значение. дней с учетом.

Если я начну свой запрос с чего-то вроде:

SELECT SubscriberID, date_trunc('Day', Date_of_Activity), count(*) as Clicks 
FROM WSD.Clicks 
WHERE Date_Of_Activity between date('2018-01-01') and date('2019-01-01') 
GROUP BY 1,2

... у каждого подписчика будет запись на определенный календарный день, только если в этот день у него был подтвержденный клик; в противном случае ни одна строка не была бы сгенерирована в исходных данных. Это вызывает инфляцию в среднем, потому что она учитывает подводные лодки, только когда они активны; человек, использующий веб-сайт один день в году с двумя щелчками, теперь равен человеку, использующему его 300 дней в году, дважды щелкающим каждый день. Как можно сделать так, чтобы запрос объявлял календарный день для каждого подписчика и назначал значение «0» в тех случаях, когда у него фактически не было зарегистрированной активности?

Для справки, эта таблица имеет только несколько столбцов:

SubscriberID (строка), Date_of_Activity (метка времени), Type_of_Activity (Строка)

Я запрашиваю данные в Афине (AWS).

1 Ответ

0 голосов
/ 24 апреля 2019

Вы можете присоединиться к списку дат. Это легко сделать в Postgres, используя generate_series():

select c.subscriberid, 
       d.day::date as date_of_activity, 
       count(c.date_of_activity) as clicks 
from generate_series(date '2018-01-01', date '2018-12-31', interval '1' day) as d(day)
  left join clicks c on c.date_of_activity::date = d.day::date 
group by 1,2
order by 1,2;

count() игнорирует null значения, и при левом соединении в столбцах clicks будет возвращено null, если совпадений нет. Так что count(c.Date_Of_Activity) вернет ноль за эти дни.

Однако это покажет также пустые значения для subscriberid. Если вы хотите создать поддельные строки для каждой комбинации subscriberid / date_of_activity, вам необходимо перекрестное объединение со списком всех подписчиков. Обратите внимание, что это даст вам (number of subscribers) * 365 строк в вашем результате! Если у вас миллионы подписчиков, это может быть не то, что вам нужно:

select s.subscriberid, 
       d.day::date as date_of_activity, 
       count(c.date_of_activity) as clicks 
from generate_series(date '2018-01-01', date '2018-12-31', interval '1' day) as d(day)
  cross join subscribers s
  left join clicks c on c.date_of_activity::date = d.day::date 
group by 1,2
order by 1,2;

Онлайн пример: https://rextester.com/QIGI84548

...