Hive SQL 面试题 - 统计每日新增用户

1 需求

从用户登录明细表(user_login_detail)中查询每天的新增用户数,若一个用户在某天登录了,且在这一天之前没登录过,则认为该用户为这一天的新增用户。

  • 用户登录明细表:user_login_detail
user_id(用户id)ip_address(ip地址)login_ts(登录时间)logout_ts(登出时间)
101180.149.130.1612021-09-21 08:00:002021-09-27 08:30:00
102120.245.11.22021-09-22 09:00:002021-09-27 09:30:00
10327.184.97.32021-09-23 10:00:002021-09-27 10:30:00
  • 期望结果
login_date_first (日期)user_count (新增用户数)
2021-09-211
2021-09-221
2021-09-231
2021-09-241
2021-09-251
2021-09-261
2021-09-271
2021-10-042
2021-10-061

2 解答

  • 思路

观察用户登录明细表,需要使用到的信息有 用户 id用户登录时间 这两个字段,这里认为用户都被限制为单点登录,所以登出时间字段用不到。

考虑使用开窗函数中的排名函数对每一个用户按照登录时间进行排名,再对排名进行限定,仅取第一次登录的日期作为新用户首次登录,最后根据日期分组,查看每天存在多少个用户即可。

  • 实现

1 开窗,此处使用 row_number 进行编号,over 中指定 partition by user_id 表示针对每一个用户进行编号,指定 order by login_ts 表示按照 login_ts 排序之后再编号

SELECT 
	user_id,
  	substr(login_ts, 1, 10) dt,
	row_number() over (partition by user_id order by login_ts) rn
from user_login_detail
user_iddtrn
1012021-09-211
1012021-09-272
1012021-09-283
1012021-09-294
1012021-09-305
10102021-10-091
10102021-09-272

2 聚合,在第一步的结果上,按照 dt 字段进行聚合,结合 sum(if()) 进行统计,最后使用 HAVING 进行聚合结果的筛选

select dt login_date_first, sum(if(rn == 1, 1, 0)) user_count from (
	SELECT 
    	user_id,
  		substr(login_ts, 1, 10) dt,
		row_number() over (partition by user_id ORDER by login_ts) rn
	from user_login_detail
) t1 group by dt HAVING sum(if(rn == 1, 1, 0)) != 0 order by dt;
login_date_firstuser_count
2021-09-211
2021-09-221
2021-09-231
2021-09-241
2021-09-251
2021-09-261
2021-09-271
2021-10-042
2021-10-061
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值