当前日期缺失时的 30 天滚动/移动总和
Posted
技术标签:
【中文标题】当前日期缺失时的 30 天滚动/移动总和【英文标题】:30-day rolling/moving sum when current date is missing 【发布时间】:2016-04-26 10:36:58 【问题描述】:我有一个表 (view_of_referred_events
),它存储给定页面的访问者数量。
date country_id referral product_id visitors
2016-04-01 216 pl 113759 1
2016-04-03 216 pl 113759 1
2016-04-06 216 pl 113759 13
2016-04-07 216 pl 113759 10
我想计算此产品的 30 天滚动/移动总和,即使是那些缺失的日子。所以最终的结果应该是这样的:
date country_id referral product_id cumulative_visitors
2016-04-01 216 pl 113759 1
2016-04-02 216 pl 113759 1
2016-04-03 216 pl 113759 2
2016-04-04 216 pl 113759 2
2016-04-05 216 pl 113759 2
2016-04-06 216 pl 113759 15
2016-04-07 216 pl 113759 25
现在,这是一个简单的表示,因为我有几十个不同的 country_id
、referral
和 product_id
。我无法预先创建包含 date
、country_id
、referral
和 product_id
的所有可能组合的表,因为考虑到表的大小,这将变得无法治疗。如果特定的 date
、country_id
、referral
和 product_id
以前不存在,我也不想在决赛桌中有一行。
我在想如果view_of_referred_events
当天没有访问者,是否有一种简单的方法告诉 Impala 使用前一行(前一天)的值。
我编写了这个查询,其中list_of_dates
是一个表格,其中包含从 4 月 1 日到 4 月 7 日的日期列表。
select
t.`date`,
t.country_id,
t.referral,
t.product_id,
sum(visitors) over (partition by t.country_id, t.referral, t.product_id order by t.`date`
rows between 30 preceding and current row) as cumulative_sum_visitors
from (
selec
d.`date`,
re.country_id,
re.referral,
re.product_id,
sum(visitors) as visitors
from list_of_dates d
left outer join view_of_referred_events re on d.`date` = re.`date`
and re.referral = "pl"
and re.product_id = "113759"
and re.country_id = "216"
group by d.`date`, re.country_id, re.referral, re.product_id
) t
order by t.`date` asc;
这会返回类似于我想要的东西,但不完全一样。
date country_id referral product_id cumulative_visitors
2016-04-01 216 pl 113759 1
2016-04-02 NULL NULL NULL NULL
2016-04-03 216 pl 113759 2
2016-04-04 NULL NULL NULL NULL
2016-04-05 NULL NULL NULL NULL
2016-04-06 216 pl 113759 15
2016-04-07 216 pl 113759 25
【问题讨论】:
请澄清:您的文字和标题是关于累积的。该查询建议您需要 30 天的滚动/移动总和。 【参考方案1】:我添加了另一个子查询来获取分区中最后一行的值。我不确定您使用的是哪个版本的 hive/impala,last_value(column_name, ignore null values true/false)
是语法。
我假设您正在尝试查找 30 天(月)内的累积计数,我建议使用月字段对行进行分组。月份可以来自您的维度表list_of_dates
或仅来自substr(date, 1, 7)
,并获得超过..rows unbounded preceding and current row
的访问者的累积计数。
查询:
select
`date`,
country_id,
referral,
product_id,
sum(visitors) over (partition by country_id, referral, product_id order by `date`
rows between 30 preceding and current row) as cumulative_sum_visitors
from (select
t.`date`,
-- get the last not null value from the partition window w for country_id, referral & product_id
last_value(t.country_id, true) over w as country_id,
last_value(t.referral, true) over w as referral
last_value(t.product_id, true) over w as product_id
if(visitors = null, 0, visitors) as visitors
from (
select
d.`date`,
re.country_id,
re.referral,
re.product_id,
sum(visitors) as visitors
from list_of_dates d
left outer join view_of_referred_events re on d.`date` = re.`date`
and re.referral = "pl"
and re.product_id = "113759"
and re.country_id = "216"
group by d.`date`, re.country_id, re.referral, re.product_id
) t
window w as (partition by t.country_id, t.referral, t.product_id order by t.`date`
rows between unbounded preceding and unbounded following)) t1
order by `date` asc;
【讨论】:
很遗憾,当前版本的 Impala 不支持在LAST_VALUE
函数中忽略 NULL
值。【参考方案2】:
我不确定性能会有多好,但您可以通过将数据聚合两次并为第二次聚合增加 30 天并否定计数来做到这一点。
类似这样的:
with t as (
select d.`date`, re.country_id, re.referral, re.product_id,
sum(visitors) as visitors
from list_of_dates d left outer join
view_of_referred_events re
on d.`date` = re.`date` and
re.referral = 'pl' and
re.product_id = 113759 and
re.country_id = 216
group by d.`date`, re.country_id, re.referral, re.product_id
)
select date, country_id, referral, product_id,
sum(sum(visitors)) over (partition by country_id, referral, product_id order by date) as visitors
from ((select date, country_id, referral, product_id, visitors
from t
) union all
(select date_add(date, 30), country_id, referral, product_id, -visitors
from t
)
) tt
group by date, country_id, referral, product_id;
【讨论】:
我认为您在定义t
时忘记了 GROUP BY d.
date, re.country_id, re.referral, re.product_id
。除此之外,此查询不会继承没有访问者的那些日子的值。事实上,在那些日子里,country_id
、referral
、product_id
和 visitors
的值将是 NULL
。
@Gianluca 。 . .谢谢你。至于第二点,我以为你不想要没有变化的日子。以上是关于当前日期缺失时的 30 天滚动/移动总和的主要内容,如果未能解决你的问题,请参考以下文章