我正在做一些有关网站订户活动的研究。具体来说,我希望看到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
...如果每个订阅者在该日期确认点击,则仅在该日历日有一个条目;否则,源数据中将不会生成任何行。这会导致平均通胀,因为仅在潜艇活跃时才考虑在内。现在,一年中有一天点击2次使用该网站的用户等于一年中有300天每天两次单击该网站的用户。在他们实际上没有记录的活动的情况下,如何使查询为每个订户声明一个日历日并将值赋为“ 0”?
作为参考,该表仅包含几列:
SubscriberID(字符串),Date_of_Activity(时间戳),Type_of_Activity (字符串)
我正在雅典娜(AWS)中查询数据。
答案 0 :(得分:0)
您可以加入日期列表。在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
的值,如果没有匹配项,则左联接将在null
的列中返回clicks
。因此count(c.Date_Of_Activity)
在那几天将返回零。
这也将显示subscriberid
的空值。如果要为每个订户id / 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;