京东Hive SQL面试题:京东店铺访问统计的终极解法(附幽默彩蛋)
大家好,今天我们来破解一道京东跳动高频Hive SQL面试题——京东店铺访问统计。题目看似简单,但隐藏着窗口函数和分组聚合的巧妙配合。准备好你的咖啡,我们开始飙车!
题目描述
表结构:访问日志表Visit
user_id:访客ID(用户唯一标识)shop:被访问的店铺名称
需求:
- 统计每个店铺的UV(独立访客数)
- 输出每个店铺访问次数Top3的访客信息(店铺名、用户ID、访问次数)
解题思路
问题一:每个店铺的UV
UV即Unique Visitor,统计逻辑简单粗暴:按店铺分组,去重统计用户数。
但要注意:50万店铺的数据量下,COUNT(DISTINCT)可能成为性能瓶颈。不过面试场景中,先保证逻辑正确,优化问题可后续讨论。
代码实现:
SELECT
shop,
COUNT(DISTINCT user_id) AS uv
FROM Visit
GROUP BY shop;
问题二:Top3访客信息
这里需要两步操作:
- 计算每个用户在各店铺的访问次数:按店铺和用户分组聚合
- 窗口函数排名:按访问次数降序排列,取前三名
代码实现:
SELECT
shop,
user_id,
visit_count
FROM (
SELECT
shop,
user_id,
visit_count,
RANK() OVER (PARTITION BY shop ORDER BY visit_count DESC) AS rk
FROM (
SELECT
shop,
user_id,
COUNT(*) AS visit_count -- 统计访问次数
FROM Visit
GROUP BY shop, user_id
) t1
) t2
WHERE rk <= 3;
技术细节剖析
-
为什么用
RANK()而不用ROW_NUMBER()?RANK()允许并列排名(比如两个用户访问次数相同则共享名次),而ROW_NUMBER()强制顺序编号。- 但注意:如果出现并列第三名,
RANK()可能导致结果超过3条。若题目要求严格3条,可改用ROW_NUMBER()。
-
性能优化小贴士
- 如果数据量极大,可先对
shop和user_id建立联合索引。 - 使用
MAPJOIN对小表进行缓存优化(但本题中店铺数为50W,可能不适用)。
- 如果数据量极大,可先对
幽默彩蛋
面试官:如果某个店铺的Top3有10个用户并列怎么办?
你:那我建议京东给这10位“铁杆粉丝”颁发【最佳钉子户】奖杯,并附赠终身VIP——毕竟他们撑起了店铺的KPI!
(正经回答:需明确需求是否允许并列,或用DENSE_RANK()处理名次密度)
总结
- UV统计:分组去重是核心
- TopN问题:窗口函数+子查询的黄金组合
- 面试加分点:讨论排名函数差异和性能优化策略
搞定这道题,你离字节的Offer又近了一步!🚀

&spm=1001.2101.3001.5002&articleId=145742083&d=1&t=3&u=7c8bc62ee76c4046b369a1f332ca216c)
6230

被折叠的 条评论
为什么被折叠?



