如果零日没有生成 rows/data,如何获得每人每天的平均值 activity?

How to get average activity per person per day if a zero-day generates no rows/data?

我正在做一些关于 activity 网站订阅者的研究。具体来说,我想查看 2018 年每位订阅者每天的平均点击次数。不幸的是,提供给我的数据 table 没有考虑订阅者根本不参与网站的天数,但我需要考虑零日漏洞。

如果我以这样的方式开始查询:

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

...每个订阅者只有在特定日历日发生了确认点击时才会有一个条目;否则,源数据中不会生成任何行。这导致平均 inflation,因为它只考虑活跃的潜艇;一年中一天使用该网站并点击两次的人现在等于一年中 300 天每天使用该网站的人每天点击两次。我如何让查询为每个订阅者声明一个日历日,并在他们实际上没有记录 activity 的情况下赋予值“0”?

供参考,此 table 只有几列:

SubscriberID (string), Date_of_Activity (timestamp), Type_of_Activity (string)

我正在 Athena (AWS) 中查询数据。

您可以根据日期列表加入。这在 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 的列中 return null。所以 count(c.Date_Of_Activity) 将 return 在那些日子里归零。

然而,这也会显示 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