牛客网 SQL大厂面试真题篇 SQL11 每天的日活数及新用户占比

描述

用户行为日志表tb_user_log

iduidartical_idin_timeout_timesign_cin
110190012021-10-31 10:00:002021-10-31 10:00:090
210290012021-10-31 10:00:002021-10-31 10:00:090
310102021-11-01 10:00:002021-11-01 10:00:421
41029001

2021-11-01 10:00:00

2021-11-01 10:00:090
510890012021-11-01 10:00:012021-11-01 10:00:500
610890012021-11-02 10:00:012021-11-02 10:00:500
710490012021-11-02 10:00:28

2021-11-02 10:00:50

0
810690012021-11-02 10:00:282021-11-02 10:00:500
910890012021-11-03 10:00:012021-11-03 10:00:500
1010990022021-11-03 11:00:552021-11-03 11:00:590
1110490032021-11-03 11:00:452021-11-03 11:00:550
1210590032021-11-03 11:00:532021-11-03 11:00:590
1310690032021-11-03 11:00:452021-11-03 11:00:550

(uid-用户ID, artical_id-文章ID, in_time-进入时间, out_time-离开时间, sign_in-是否签到)

问题:统计每天的日活数及新用户占比

  • 新用户占比=当天的新用户数÷当天活跃用户数(日活数)。
  • 如果in_time-进入时间out_time-离开时间跨天了,在两天里都记为该用户活跃过。
  • 新用户占比保留2位小数,结果按日期升序排序。

输出示例

示例数据的输出结果如下

dtdauuv_new_ratio
2021-10-3021.00
2021-11-0130.33
2021-11-0230.67
2021-11-0350.40

解释:

2021年10月31日有2个用户活跃,都为新用户,新用户占比1.00;

2021年11月1日有3个用户活跃,其中1个新用户,新用户占比0.33;

题解:

总体逻辑如下:

# 1.计算用户第一次登录的时间
# 2.根据1计算每天的新用户数
# 3.计算每日活跃用户数
# 4.把每日活跃用户数和每天的新用户数做连接,连接条件是日期
# 5.计算新用户数/活跃用户数,因为连接的两个表里面都已经按照日期分组了,所以连接后的表不需要再分组了

 第一步:先统计每个用户的最小登录日期,再统计每个日期的用户数,即为每天的新用户数


select dt,count(1) new_user
from(
      -- 用户第一次登录时间
        select uid,min(date(in_time)) dt
        from tb_user_log
        group by uid
)t
group by dt

第二步:每日活跃用户数

select dt,count(distinct uid) dau
from(
        select uid,date(in_time) dt from tb_user_log 
        union all
        select uid,date(out_time) dt from tb_user_log
)t
group by dt

 

第三步:将两个表作右连接(因为有可能某天没有新用户数,因此要右连接),再计算新用户占比

select t2.dt,dau,ifnull(round(new_user/dau,2),0) uv_new_ratio
from(
    -- 每天的新用户数
    select dt,count(1) new_user
    from(
        -- 用户第一次登录时间
        select uid,min(date(in_time)) dt
        from tb_user_log
        group by uid)t
    group by dt
)t1
-- 因为有可能某天没有新用户数,因此要右连接
right join(
    -- 每日活跃用户数
    select dt,count(distinct uid) dau
    from(
        select uid,date(in_time) dt from tb_user_log  -- 先在里面date()
        union all
        select uid,date(out_time) dt from tb_user_log
    )t
    group by dt
)t2
on t1.dt=t2.dt

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值