如何在 HiveQL 中计算每个城市中最受欢迎的设备、操作系统、浏览器?
Posted
技术标签:
【中文标题】如何在 HiveQL 中计算每个城市中最受欢迎的设备、操作系统、浏览器?【英文标题】:How do I calculate the most popular device, os, browser in each city in HiveQL? 【发布时间】:2018-12-24 11:54:09 【问题描述】:我有一个包含用户代理字符串的表(我将其解析为browser
、os
和device
列)和城市id
。我想为每个city
计算最流行的browser
、os
和device
。
这是我的尝试:
select device os, browser, name, MAX(hits) as pop from
(select uap.device, uap.os, uap.browser, name, COUNT(*) as hits
from (select * from browserdata join citydata on cityid=id) t
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser
GROUP BY uap.device, uap.os, uap.browser, name) t2
GROUP BY name;
所以,最里面的子查询,别名为t
只是将我的表连接到另一个将id
映射到城市name
s 的表上,所以我可以看到实际的name
s,而不是城市@987654335 @'s 在输出中。
然后,名为 t2
的子查询计算复合键的数量(device
、browser
、os
、city
)。外部查询将所有内容分组到name
窗口中,并提取用户数最多的行。
我得到的错误是这样的:
失败:SemanticException [错误 10025]:第 1:7 行表达式不在 GROUP BY 键“设备”中
我明白这意味着什么。它说我需要将device
包含到group by
中,但是如果我这样做了,那么它就不会计算我想要的。如何修复我的查询?
另外,我注意到我的一些 hive 查询在 mapreduce 上运行,但不在 tez 上运行。这是为什么呢?
【问题讨论】:
样本数据、所需结果和格式化查询真的很有帮助。 @GordonLinoff 第一个表(browserdata)有(useragent,cityid)行,第二个(citydata)有(cityid,cityname)行。 @GordonLinoff ideone.com/SCjb1q 我是在别人的帮助下写的,但现在发现 hive 不支持横向连接... 【参考方案1】:使用分析函数可以消除不必要的连接:
WITH
t1 as
(select * from browserdata join citydata on cityid=id),
t2 as
(select uap.device as device, uap.os as os, uap.browser as browser, name as cityname
from t1
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser),
t3 as
(select t2.cityname as cityname, t2.device as device, t2.browser as browser, t2.os as os, count(*) as count from t2 group by t2.cityname, t2.os, t2.device, t2.browser)
select cityname, maximum, device, os, browser
from
(select cityname, device, browser, os,
max(count) over(partition by cityname) as maximum,
dense_rank() over (partition by cityname order by count desc ) as rnk
from t3
) s where rnk =1
;
【讨论】:
嘿,非常感谢。顺便说一句,您在“oartition”中有错字。【参考方案2】:WITH t1 as
(select * from browserdata join citydata on cityid=id),
t2 as
(select uap.device as device, uap.os as os, uap.browser as browser, name as cityname
from t1
lateral view ParseUserAgentUDTF(UserAgent) uap as device, os, browser),
t3 as
(SELECT t2.cityname as cityname, t2.device as device, t2.browser as browser, t2.os as os, COUNT(*) as count FROM t2 GROUP BY t2.cityname, t2.os, t2.device, t2.browser),
t4 as
(select cityname, MAX(count) as maximum from t3 group by cityname)
select t4.cityname, t4.maximum, t3.device, t3.os, t3.browser
from t4 join t3 on t4.cityname=t3.cityname and t4.maximum=t3.count;
这行得通,但是我想知道是否有办法优化它...
【讨论】:
这不应该是问题的一部分吗? @leftjoin 当我写这个问题时,我想要一个有效的查询,而这个有效,它只是效率不高...... @leftjoin 你对分析函数的改进也失败了......我想它需要进一步优化,你知道怎么做吗?在 mapreduce 上一切正常,但在 tez 上失败。 @leftjoin ***.com/questions/53915059/… 在这里。我不明白发生了什么,没有例外。 @leftjoin 如果我执行“yarn logs -applicationId ...”,日志很大,很难诊断发生了什么。以上是关于如何在 HiveQL 中计算每个城市中最受欢迎的设备、操作系统、浏览器?的主要内容,如果未能解决你的问题,请参考以下文章
Ubuntu以40%占比,成为OpenStack部署中最受欢迎操作系统