首页 > 试题广场 >

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

[编程题]每天的日活数及新用户占比
  • 热度指数:63931 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

用户行为日志表tb_user_log

id uid artical_id in_time out_time sign_cin
1 101 9001 2021-10-31 10:00:00 2021-10-31 10:00:09 0
2 102 9001
2021-10-31 10:00:00 2021-10-31 10:00:09 0
3 101 0 2021-11-01 10:00:00 2021-11-01 10:00:42 1
4 102 9001
2021-11-01 10:00:00
2021-11-01 10:00:09 0
5 108 9001
2021-11-01 10:00:01 2021-11-01 10:00:50
0
6
108 9001 2021-11-02 10:00:01
2021-11-02 10:00:50
0
7 104 9001 2021-11-02 10:00:28
2021-11-02 10:00:50
0
8
106 9001 2021-11-02 10:00:28 2021-11-02 10:00:50
0
9
108 9001 2021-11-03 10:00:01 2021-11-03 10:00:50
0
10 109 9002
2021-11-03 11:00:55 2021-11-03 11:00:59 0
11
104 9003
2021-11-03 11:00:45
2021-11-03 11:00:55
0
12 105 9003
2021-11-03 11:00:53
2021-11-03 11:00:59
0
13 106 9003
2021-11-03 11:00:45
2021-11-03 11:00:55
0
(uid-用户ID, artical_id-文章ID, in_time-进入时间, out_time-离开时间, sign_in-是否签到)


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

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

输出示例
示例数据的输出结果如下

dt dau uv_new_ratio
2021-10-30 2 1.00
2021-11-01
3 0.33
2021-11-02
3 0.67
2021-11-03
5 0.40

解释:
2021年10月31日有2个用户活跃,都为新用户,新用户占比1.00;
2021年11月1日有3个用户活跃,其中1个新用户,新用户占比0.33;
示例1

输入

DROP TABLE IF EXISTS tb_user_log;
CREATE TABLE tb_user_log (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid INT NOT NULL COMMENT '用户ID',
    artical_id INT NOT NULL COMMENT '视频ID',
    in_time datetime COMMENT '进入时间',
    out_time datetime COMMENT '离开时间',
    sign_in TINYINT DEFAULT 0 COMMENT '是否签到'
) CHARACTER SET utf8 COLLATE utf8_bin;

INSERT INTO tb_user_log(uid, artical_id, in_time, out_time, sign_in) VALUES
  (101, 9001, '2021-10-31 10:00:00', '2021-10-31 10:00:09', 0),
  (102, 9001, '2021-10-31 10:00:00', '2021-10-31 10:00:09', 0),
  (101, 0, '2021-11-01 10:00:00', '2021-11-01 10:00:42', 1),
  (102, 9001, '2021-11-01 10:00:00', '2021-11-01 10:00:09', 0),
  (108, 9001, '2021-11-01 10:00:01', '2021-11-01 10:01:50', 0),
  (108, 9001, '2021-11-02 10:00:01', '2021-11-02 10:01:50', 0),
  (104, 9001, '2021-11-02 10:00:28', '2021-11-02 10:00:50', 0),
  (106, 9001, '2021-11-02 10:00:28', '2021-11-02 10:00:50', 0),
  (108, 9001, '2021-11-03 10:00:01', '2021-11-03 10:01:50', 0),
  (109, 9002, '2021-11-03 11:00:55', '2021-11-03 11:00:59', 0),
  (104, 9003, '2021-11-03 11:00:45', '2021-11-03 11:00:55', 0),
  (105, 9003, '2021-11-03 11:00:53', '2021-11-03 11:00:59', 0),
  (106, 9003, '2021-11-03 11:00:45', '2021-11-03 11:00:55', 0);

输出

2021-10-31|2|1.00
2021-11-01|3|0.33
2021-11-02|3|0.67
2021-11-03|5|0.40
头像 盐咸咸
发表于 2022-03-25 16:05:43
和之前一样的逻辑,理顺了之后越做越快,6行代码搞定。 一、题目理解 统计每天的日活数及新用户占比 新用户占比=当天的新用户数÷当天活跃用户数(日活数)。 如果in_time-进入时间和out_time-离开时间跨天了,在两天里都记为该用户 展开全文
头像 牛客943886824号
发表于 2021-12-06 16:03:16
select a.dt,count(distinct a.uid) dau,round(count(distinct b.uid)/count(distinct a.uid),2) from       展开全文
头像 大风在睡觉
发表于 2022-04-17 22:12:12
思路1:日活就是每天访问的不同用户数,所以我们首先要得到一张登录表,登录表记录了每天登录的用户,并按天对用户进行了去重,也就是下面的 t1。而要统计新用户的占比,我们就需要识别每天登录用户中哪些用户是新用户(即第一次登录)。一个可行的思路是,使用窗口函数对每个用户的登录日期进行排序得到下面的 t2。 展开全文
头像 通辽可汗克鸽勃
发表于 2021-12-14 13:22:45
这题算是比较简单的了,这次求新顾客用的累计次数和为1 而不是链接的方法,算是一种新的思路了,大家可以看一看! 因为之前已经说过了如何进行日期的拆分和求顾客的登录次数,说以不在赘述,代码如下 select date,count(uid) as dau, round( sum(if(times= 展开全文
头像 牛客368501572号
发表于 2021-12-15 19:09:33
select      t1.dt dt,     count(distinct t1.uid) dau,     round(count( 展开全文
头像 webary
发表于 2021-12-04 11:13:45
每天的日活数及新用户占比 明确题意: 统计每天的日活数及新用户占比,新用户占比=当天的新用户数÷当天活跃用户数(日活数)。 如果in_time和out_time跨天了,在两天里都记为该用户活跃过。 新用户占比保留2位小数,结果按日期升序排序 问题分解: 计算每天的日活数(生成子表t_dau): 展开全文
头像 王尼玛呢
发表于 2022-01-29 17:30:02
稍微需要注意的点: 跨天活跃的数据,算作两条活跃记录。 拿到活跃日期,和最早的活跃日期(要开窗记录),就可以区分出是否是新用户 SQL with t1 as ( -- t1表 uid | 活跃日期 | 最早活跃日期 SELECT uid,DATE(in_time) dt,DATE 展开全文
头像 风雪行
发表于 2022-07-26 13:16:11
这里先贴个不用窗口函数的常规思路的解法: 首先是in_time, out_time跨天都计为活跃的问题, 代码如下, 用union合并, 这样in_time和out_time两列转一列, 在根据日期分组, count(distinct t1.uid) 得到每日dau select dat 展开全文
头像 视星等无穷
发表于 2022-04-11 12:50:36
1.先得到用户活跃表(用union去重) select uid, date(in_time) dt from tb_user_log union select uid,date(out_time) dt from tb_user_log 2.得到每名用户最早出现的时间 select uid,mi 展开全文
头像 ccc不叫444
发表于 2022-05-14 11:49:47
# 难点1:如果in_time和out_time跨天了,在两天里都记为该用户活跃过。 # 那就union,把两个时间合并成一个字段;因为最终是计算“每天的用户数” # 难点2:新用户占比,每天的"新"都是相对前面的所有日期而言的 # 看到这种就想到窗口函数了, 展开全文