Hive Group by 后自我加入
Posted
技术标签:
【中文标题】Hive Group by 后自我加入【英文标题】:Hive Group by after self join 【发布时间】:2014-05-12 15:45:43 【问题描述】:伙计们,
我们有一个要求,我们希望在将 HIVE 表与 self 连接后应用 group by 子句。
例如数据
CUSTOMER_NAME,PRODUCT_NAME,PURCHASE_PRICE
customer1,product1,20
customer1,product2,30
customer1,product1,25
现在我们要通过考虑所有产品的总和以及随后按 CUSTOMER_NAME、PRODUCT_NAME 分组的结果集来获取客户(仅进行价格总和后的前 5 个客户,产品名称不存在于子查询中)
select customer_name,product_name,sum(purchase_price)
from customer_prd cprd
Join (select customer_name,sum(purchase_prices) order by sum group by customer_name limit 5) cprdd
where cprd.customer_name = cprdd.customer_name group by customer_name,product_name
收到错误消息说不能在 HIVE 中像这样分组?
【问题讨论】:
【参考方案1】:加入后,您的列名变得不明确。 Hive 不知道您是否关心连接左侧或右侧的那个。在这种情况下,这无关紧要,因为您正在对它们进行内部连接,但 hive 不够聪明,无法弄清楚这一点。试试这个:
select cprd.customer_name, cprd.product_name, sum(purchase_price)
from customer_prd cprd
Join (select customer_name, sum(purchase_price) as sum from customer_prd group by customer_name order by sum desc limit 5) cprdd
where cprd.customer_name = cprdd.customer_name group by cprd.customer_name, cprd.product_name;
【讨论】:
【参考方案2】:我认为 Joe K 是正确的,但我会重新考虑您在做什么,并完全避免加入,并使用 Brickhouse 库 (http://github.com/klout/brickhouse) 中提供的 'collect' 或 'collect_max' UDF。先按产品求和,然后同时收集和求和。
SELECT customer_name, sum(purchases) as total_purchases, collect( product_name, purchases) as product_map
FROM
( SELECT customer_name, product_name, sum(purchase_prices) AS purchases
FROM customer_prd
GROUP BY customer_name, product_name
) sp
GROUP BY customer_name
ORDER BY sum(purchases)
LIMIT 5;
这仍会导致排序以获取前 5 名客户。如果您有一个大长尾的小客户,但有几个大客户鲸鱼,您可以添加一个“HAVING sum(purchases) >”来减少要排序的记录的大小。
【讨论】:
以上是关于Hive Group by 后自我加入的主要内容,如果未能解决你的问题,请参考以下文章
hive distribute by 和group by 的区别