题解 | #每天的日活数及新用户占比#

每天的日活数及新用户占比

http://www.nowcoder.com/practice/dbbc9b03794a48f6b34f1131b1a903eb

和之前一样的逻辑,理顺了之后越做越快,6行代码搞定。

一、题目理解

  • 统计每天的日活数及新用户占比
  • 新用户占比=当天的新用户数÷当天活跃用户数(日活数)。
  • 如果in_time-进入时间和out_time-离开时间跨天了,在两天里都记为该用户活跃过。
  • 新用户占比保留2位小数,结果按日期升序排序。
这几句话给的核心信息是,in_time和out_time都算作是活跃日,同时要把用户首次登录的日期找出来,最后再计算新用户占比。

二、解题步骤

1)老方法,先建立一张拥有基本信息的用户活跃基础表
  • 这张表要包含用户id,活跃日,成为新用户的日期。因为用户可能1天活跃N次,所以要做去重处理。
  • 活跃日直接并联in_time和out_time
  • 成为新用户日期,用窗口函数来取:MIN(DATE(in_time))OVER(PARTITION BY uid)  AS new_dt
代码如下:
SELECT DISTINCT uid,DATE(in_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
UNION
SELECT DISTINCT uid,DATE(out_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
2)定义新用户
如果dt=new_dt那这天就是用户首次登录成为新用户的日子啦~
WITH t1 AS(
SELECT DISTINCT uid,DATE(in_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
UNION
SELECT DISTINCT uid,DATE(out_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
)
SELECT uid,dt,IF(dt=new_dt,1,0) '是否为新用户(是为1,不是为0)'
FROM t1;

3)计算新用户占比,结果按照日期升序,输出结果。
  • 日活:COUNT(1)
  • 新用户数:SUM(是否为新用户)
  • 新用户占比:ROUND(SUM(新用户)/COUNT(1),2)
WITH t1 AS(
SELECT DISTINCT uid,DATE(in_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
UNION
SELECT DISTINCT uid,DATE(out_time) dt,MIN(DATE(in_time))OVER(PARTITION BY uid) new_dt FROM tb_user_log
)
SELECT dt,COUNT(1) dau,ROUND(SUM(IF(dt=new_dt,1,0))/COUNT(1),2) uv_new_ratio
FROM t1 GROUP BY dt ORDER BY dt ASC;
完成啦~是不是很好理解~

SQL解题集 文章被收录于专栏

这是牛客SQL相关的解题集

全部评论
ROUND(SUM(IF(dt=new_dt,1,0))/COUNT(1),2) 可以直接改成 ROUND(avg(dt=new_dt),2) ,能省掉if和count
5 回复 分享
发布于 2022-07-19 00:29
其实不用distinct 吧? union的时候就去重了
3 回复 分享
发布于 2022-08-22 18:42 北京
有点没明白,假如跨天了不就有两个new_dt了嘛
2 回复 分享
发布于 2022-07-31 16:20
count(distinct uid)转换到count(1)这里求指点
2 回复 分享
发布于 2022-06-20 16:38
有一个问题,union可以处理in_time和out_time跨一天的情况,当in_time和out_time跨多天(大于一天)的时候,union就处理不了了。
1 回复 分享
发布于 2024-02-05 20:44 广东
一直没理解,在什么情况下用窗口函数,求大佬指点
1 回复 分享
发布于 2022-05-23 21:16
太棒了,我逐渐理解一切
点赞 回复 分享
发布于 05-24 21:29 湖北
楼主厉害!请受我一拜!
点赞 回复 分享
发布于 01-18 10:30 北京
请问以下ROUND(SUM(IF(dt=new_dt,1,0))/COUNT(1),2),为什么前面用SUM而不是用count呢
点赞 回复 分享
发布于 2024-07-24 11:33 山西
还是不会
点赞 回复 分享
发布于 2023-06-11 17:24 重庆
楼主厉害,学习到了。
点赞 回复 分享
发布于 2023-06-09 16:00 广东
泰裤辣!
点赞 回复 分享
发布于 2023-04-27 14:36 美国
牛逼
点赞 回复 分享
发布于 2022-11-13 20:21 陕西
太强了!!学习!
点赞 回复 分享
发布于 2022-10-25 16:33 广东
调理清晰, 谢谢, 学到了
点赞 回复 分享
发布于 2022-07-26 13:04
请问count(1)为什么可以代表日活呢 谢谢~
点赞 回复 分享
发布于 2022-06-20 16:36
条理清晰。 WITH 真香。大佬🐂🍺
点赞 回复 分享
发布于 2022-05-26 19:14
为什么要UNION呢?
点赞 回复 分享
发布于 2022-04-07 10:27

相关推荐

评论
160
16
分享

创作者周榜

更多
牛客网
牛客企业服务