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)的主要内容,如果未能解决你的问题,请参考以下文章

Hive06-HiveQL:查询

Hive 数组类型的求和值

HiveQL

Hive知识总结

HiveQL

大数据之-HIVE入门(二十)