Hive:对指定组求和(HiveQL)
Posted
技术标签:
【中文标题】Hive:对指定组求和(HiveQL)【英文标题】:Hive: Sum over a specified group (HiveQL) 【发布时间】:2014-08-01 14:03:51 【问题描述】:我有一张桌子:
key product_code cost
1 UK 20
1 US 10
1 EU 5
2 UK 3
2 EU 6
我想找到每组“键”的所有产品的总和并附加到每一行。例如key = 1,求所有产品的成本总和(20+10+5=35),然后将结果追加到key = 1对应的所有行。所以最终结果:
key product_code cost total_costs
1 UK 20 35
1 US 10 35
1 EU 5 35
2 UK 3 9
2 EU 6 9
我更愿意在不使用子连接的情况下执行此操作,因为这样做效率低下。我最好的想法是将over
函数与sum
函数结合使用,但我无法让它工作。我最好的尝试:
SELECT key, product_code, sum(costs) over(PARTITION BY key)
FROM test
GROUP BY key, product_code;
我看过docs,但那里太神秘了,我不知道该怎么做。我正在使用 Hive v0.12.0、HDP v2.0.6、HortonWorks Hadoop 发行版。
【问题讨论】:
你最好的尝试有什么问题? @fmx 它只是给出了一个语法错误。我一定是以错误的方式使用 over 函数 【参考方案1】:类似于@VB_ 的答案,使用BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
statement。
HiveQL 查询因此是:
SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM test;
【讨论】:
【参考方案2】:您可以使用BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
来实现这一点,而无需自连接。
代码如下:
SELECT a, SUM(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM T;
【讨论】:
快到了!这总计到当前行。我现在意识到你需要 BETWEEN UNBOUNDED PRECEDING 和 UNBOUNDED FOLLOWING 语句【参考方案3】:分析函数 sum 给出累积总和。例如,如果你这样做了:
select key, product_code, cost, sum(cost) over (partition by key) as total_costs from test
那么你会得到:
key product_code cost total_costs
1 UK 20 20
1 US 10 30
1 EU 5 35
2 UK 3 3
2 EU 6 9
这似乎不是你想要的。
相反,您应该使用聚合函数 sum,结合自连接来完成此操作:
select test.key, test.product_code, test.cost, agg.total_cost
from (
select key, sum(cost) as total_cost
from test
group by key
) agg
join test
on agg.key = test.key;
【讨论】:
有没有不使用自连接的方法?【参考方案4】:这个查询给了我完美的结果
select key, product_code, cost, sum(cost) over (partition by key) as total_costs from zone;
【讨论】:
【参考方案5】:类似的答案(如果我们使用 oracle emp table):
select deptno, ename, sal, sum(sal) over(partition by deptno) from emp;
输出如下:
deptno ename sal sum_window_0
10 MILLER 1300 8750
10 KING 5000 8750
10 CLARK 2450 8750
20 SCOTT 3000 10875
20 FORD 3000 10875
20 ADAMS 1100 10875
20 JONES 2975 10875
20 SMITH 800 10875
30 BLAKE 2850 9400
30 MARTIN 1250 9400
30 ALLEN 1600 9400
30 WARD 1250 9400
30 TURNER 1500 9400
30 JAMES 950 9400
【讨论】:
我认为 HiveSQL 没有这个功能。这是oracle sql吗? 我从那个表中获取了数据,在 hive 中创建了一个表。 (apache-hive-1.2.1) 我在 hive 中尝试了上述查询(也许你可以尝试相同)。此处复制粘贴相同的输出。【参考方案6】:上面的表格看起来像
key product_code cost
1 UK 20
1 US 10
1 EU 5
2 UK 3
2 EU 6
用户想要一个总成本如下的表格
key product_code cost total_costs
1 UK 20 35
1 US 10 35
1 EU 5 35
2 UK 3 9
2 EU 6 9
因此我们使用了以下查询
SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM test;
到目前为止一切顺利。 我还想要一个专栏,统计每个国家的出现次数
key product_code cost total_costs occurences
1 UK 20 35 2
1 US 10 35 1
1 EU 5 35 2
2 UK 3 9 2
2 EU 6 9 2
因此我使用了以下查询
SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as total_costs
COUNT(product code) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as occurences
FROM test;
很遗憾,这不起作用。我得到一个神秘的错误。为了排除我的查询中的错误,我想问我是否做错了什么。 谢谢
【讨论】:
虽然很旧,但 COUNT(product code) 应该是 COUNT(product_code) 另外我正在运行 Hive-0.13,我可以通过执行以下查询 select key,product_code, cost , sum 获得所需的结果(cost) over(partition by key), count(product_code) over(partition by product_code) as p_code_count FROM prod_key;以上是关于Hive:对指定组求和(HiveQL)的主要内容,如果未能解决你的问题,请参考以下文章