如何解决在滚动时间内按ID的不同计数日期
我正在尝试从非常大的数据集中找到经常访问者的每日趋势。在这种情况下,频繁访问者是连续3天在2个不同天使用的访问者ID。
我的数据集如下所示:
ID | Date | Location | State | Brand |
1 | 2020-01-02 | A | CA | XYZ |
1 | 2020-01-03 | A | CA | BCA |
1 | 2020-01-04 | A | CA | XYZ |
1 | 2020-01-06 | A | CA | YQR |
1 | 2020-01-06 | A | WA | XYZ |
2 | 2020-01-02 | A | CA | XYZ |
2 | 2020-01-05 | A | CA | XYZ |
这是我想要的结果。访问列中的计数等于日期列中不同天的计数,每个ID为-2天。因此,对于2020年1月5日的ID 1,在3日和4日进行了一次访问,因此计数为2。
Date | ID | Visits | Frequent Prior 3 Days
2020-01-01 |Null| Null | Null
2020-01-02 | 1 | 1 | No
2020-01-02 | 2 | 1 | No
2020-01-03 | 1 | 2 | Yes
2020-01-03 | 2 | 1 | No
2020-01-04 | 1 | 3 | Yes
2020-01-04 | 2 | 1 | No
2020-01-05 | 1 | 2 | Yes
2020-01-05 | 2 | 1 | No
2020-01-06 | 1 | 2 | Yes
2020-01-06 | 2 | 1 | No
2020-01-07 | 1 | 1 | No
2020-01-07 | 2 | 1 | No
2020-01-08 | 1 | 1 | No
2020-01-09 | 1 | null | Null
我本来尝试使用以下行来获取visits列的结果,但在该ID首次达到3的每个连续日期的最后一行,都以3结尾。
,count(ID) over (Partition by ID order by Date ASC rows between 3 preceding and current row) as visits
我在论坛上进行了搜索,但是每个类似的问题似乎都涉及计数值而不是日期,并且还无法弄清楚如何调整以获得所需的内容。非常感谢您的帮助。
解决方法
您可以按用户和日期汇总数据集,然后将窗口函数与范围框一起使用以查看前面的三行。
您没有告诉您正在运行哪个数据库-并非所有数据库都支持窗口范围,也没有相同的语法来处理文字间隔。在标准SQL中,您可以执行以下操作:
select
id,date,count(*) cnt_visits
case
when sum(count(*)) over(
partition by id
order by date
range between interval '3' day preceding and current row
) >= 2
then 'Yes'
else 'No'
end is_frequent_visitor
from mytable
group by id,date
另一方面,如果您想要为每个用户和每天(无人访问时的事件)记录,则有些不同。您可以先生成数据集,然后使用left join
带表:
select
i.id,d.date,count(t.id) cnt_visits,case
when sum(count(t.id)) over(
partition by i.id
order by d.date
rows between '3' day preceding and current row
) >= 2
then 'Yes'
else 'No'
end is_frequent_visitor
from (select distinct id from mytable) i
cross join (select distinct date from mytable) d
left join mytable t
on t.date = d.date
and t.id = i.id
group by i.id,d.date
,
我倾向于通过使用cross join
扩展窗口和访问者来扩展日期和访问者。假设数据中包含所有日期:
select i.id,count(t.id) over (partition by i.id
order by d.date
rows between 2 preceding and current row
) as cnt_visits,(case when count(t.id) over (partition by i.id
order by d.date
rows between 2 preceding and current row
) >= 2
then 'Yes' else 'No'
end) as is_frequent_visitor
from (select distinct id from t) i cross join
(select distinct date from t) d left join
(select distinct id,date from t) t
on t.date = d.date and
t.id = i.id;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。