2015-06-12 50 views
0

每组的日期范围我有一定的日期和产品类型的表总和超过在蜂巢

Product Process_Date Prod_Count 
A   2015-08-01 2 
A   2015-09-03 2 
A   2015-05-06 3 
B   2014-01-01 4 
B   2014-12-31 5 

我想每一行计算,产品的条目从过去6个月计处理日期(包括process_date)。所以输出应该看起来像

Product Process_Date Count 
A   2015-08-01 5 
A   2015-09-03 7 
A   2015-05-06 3 
B   2014-01-01 4 
B   2014-12-31 5 

目前我在做自联接

SELECT 
q.Product, q.Process_Date, SUM(Prod_Count) AS num_180days 
FROM tableT p 
INNER JOIN (
    SELECT DISTINCT Product, Process_Date 
    FROM tableT 
) q 
ON p.Product = q.Product 
WHERE Process_Date BETWEEN DATE_SUB(q.Process_Date, 180) AND q.Process_Date 
GROUP BY q.Product, q.Process_Date; 

此查询时间很长,因为表是相当大的。我想知道是否有替代使用窗口功能来做到这一点。

谢谢!

+0

子查询似乎是不必要的。为什么你不能在tableT.Product和tableT.Process_Date上分组?子查询对于Hive中的性能来说是个坏消息。 –

+0

@ chipmunkofdoom2你能否详细说明如何避免组的子查询? – Nitin

+0

通过执行GROUP BY p.Product,p.Process_Date; '。子查询似乎没有做任何事情。它只是从tableT中提取不同的产品和Process_Dates,然后再回到tableT。这应该不会影响行数。加入'p.Product'和'p.Process_Date'应该会给你相同的结果。 –

回答

4

这可以简单地通过使用Hive窗口分析函数来实现,尽管考虑到文档的状态并不明显这是真的。我发现官方的Hive文档已经过时并且经常不正确。我通过阅读Hive JIRA发现了这个宝藏。有关其他窗口分析功能功能的更多信息,请参阅原始JIRI:https://issues.apache.org/jira/browse/HIVE-4112

有一个奇怪的限制,即窗口分析函数不能包含整数乘法。解决方法是预先乘法15552000 = 60 * 60 * 24 * 180秒或180天。

SELECT 
    product, 
    process_date, 
    prod_count, 
    sum(prod_count) OVER (
     PARTITION BY product 
     ORDER BY unix_timestamp(process_date,'yyyy-MM-dd') ASC 
     RANGE BETWEEN 15552000 PRECEDING and CURRENT ROW) as count 
FROM tableT 

我希望这有助于!