数据分析经常会分析日活月活,这是互联网产品的重要指标。相比前面的 topN 和连续登录天数,日活月活这类问题的求解就友好很多,只需要对每日或者每月的用户去重,并计数,就能得到答案。下面通过题目来学习日活月活的做法。

1.牛客SQL17.平均活跃天数和月活人数[1]

描述

用户在牛客试卷作答区作答记录存储在表 exam_record 中,内容如下:

exam_record表(uid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分)

| id   | uid  | exam_id | start_time          | submit_time         | score  |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1    | 1001 | 9001    | 2021-07-02 09:01:01 | 2021-07-02 09:21:01 | 80     |
| 2    | 1002 | 9001    | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81     |
| 3    | 1002 | 9002    | 2021-09-02 12:01:01 | (NULL)              | (NULL) |
| 4    | 1002 | 9003    | 2021-09-01 12:01:01 | (NULL)              | (NULL) |
| 5    | 1002 | 9001    | 2021-07-02 19:01:01 | 2021-07-02 19:30:01 | 82     |
| 6    | 1002 | 9002    | 2021-07-05 18:01:01 | 2021-07-05 18:59:02 | 90     |
| 7    | 1003 | 9002    | 2021-07-06 12:01:01 | (NULL)              | (NULL) |
| 8    | 1003 | 9003    | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86     |
| 9    | 1004 | 9003    | 2021-09-06 12:01:01 | (NULL)              | (NULL) |
| 10   | 1002 | 9003    | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81     |
| 11   | 1005 | 9001    | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88     |
| 12   | 1006 | 9002    | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89     |
| 13   | 1007 | 9002    | 2020-09-02 12:11:01 | 2020-09-02 12:31:01 | 89     |

请计算 2021 年每个月里试卷作答区用户平均月活跃天数 avg_active_days 和月度活跃人数 mau,上面数据的示例输出如下:

| month  | avg_active_days | mau  |
| ------ | --------------- | ---- |
| 202107 | 1.50            | 2    |
| 202109 | 1.25            | 4    |

思路:需要按月统计,肯定会用到 group by 月份,在此基础上使用聚合函数即可得到答案。关于需要聚合的对象,月活较为简单,只需要对不同的 uid 进行计数。而对于用户平均活跃天数,则需要得到用户的总活跃天数和不同的用户数。不同的用户数和月活的求解方式一样,总活跃天数则需要同时读用户和日期进行去重,因为如果同一天有多个用户活跃,则最终的总活跃天数中是会计算多天的。

selectdate_format(submit_time,'%Y%m') month,round(count(distinct uid,date_format(submit_time,'%Y%m%d'))/count(distinct uid),2) avg_active_days,count(distinct uid) mau
from exam_record
where year(submit_time)=2021
group by month;
2.牛客SQL11.每天的日活数及新用户占比[2]

描述

用户行为日志表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:日活就是每天访问的不同用户数,所以我们首先要得到一张登录表,登录表记录了每天登录的用户,并按天对用户进行了去重,也就是下面的 t1。而要统计新用户的占比,我们就需要识别每天登录用户中哪些用户是新用户(即第一次登录)。一个可行的思路是,使用窗口函数对每个用户的登录日期进行排序得到下面的 t2。统计的时候进行判断,如果统计当天该用户的序号为 1,则表示用户今天是第一次登录,即为新用户。于是可以写出下面的答案:

with t1 as(      # 用户登录表,记录了用户 id 和登录时间,对每天的登录用户进行了去重select uid,date(in_time) dtfrom tb_user_logunion      # union 实现去重,union all 不去重select uid,date(out_time) dtfrom tb_user_log
),
t2 as (     # 对每个用户的登录日期进行排序,注册日期的序号是 1selectuid,dt,row_number() over(partition by uid order by dt) rnfrom t1
)
# 获得答案
selectdt,count(uid) dau,round(sum(if(rn=1,1,0))/count(uid),2) uv_new_ration
from t2
group by dt
order by dt;

思路2:同样的思路得到用户登录表 t1。每个用户的注册日期肯定在登录表中是最小的,因此用 min 函数可以得到用户登录表即下面的 t2。最后在求解答案的时候,用 t1 left join t2,关联的字段是 uid 以及日期,由于使用了 left join,t1 中每个用户所有的登录日期都得到了保留,count 计数即可得到 dau,而 t2 表中不是当天注册的用户 uid 和 reg_dt 都为null,同样使用 count 计数就能得到当天的新用户。于是可以得到下面的答案:

with t1 as(      # 用户登录表,记录了用户 id 和登录时间,对每天的登录用户进行了去重select uid,date(in_time) dtfrom tb_user_logunionselect uid,date(out_time) dtfrom tb_user_log
),
t2 as (     # 得到用户注册表selectuid,min(dt) reg_dtfrom t1group by uid
)
selectdt,count(t1.uid) dau,round(count(t2.uid)/count(t1.uid),2) uv_new_ration
from t1 left join t2 on t1.uid=t2.uid and t1.dt=t2.reg_dt
group by dt
order by dt;

Reference

[1]牛客SQL17.平均活跃天数和月活人数:https://www.nowcoder.com/practice/9e2fb674b58b4f60ac765b7a37dde1b9?tpId=240&tqId=2183005&ru=/exam/oj&qru=/ta/sql-advanced/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D240

[2]牛客SQL11.每天的日活数及新用户占比:https://www.nowcoder.com/practice/dbbc9b03794a48f6b34f1131b1a903eb?tpId=268&tqId=2285346&ru=/exam/oj&qru=/ta/sql-factory-interview/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D268

欢迎关注公众号,每天分享大数据面试题和大数据技术。

【SQL】大数据面试常考题之日活(dau)月活相关推荐

  1. 算法人必懂的进阶SQL知识,4道面试常考题

    (图片付费下载自视觉中国) 作者 | 石晓文 来源|小小挖掘机(ID:wAlsjwj) 近期在不同群里有小伙伴们提出了一些在面试和笔试中遇到的Hive SQL问题,Hive作为算法工程师的一项必备技能 ...

  2. 2021超全大数据面试宝典,吐血总结十万字,大数据面试收藏这一篇就够了

    本文最新版已发布至公众号[五分钟学大数据] 获取此套面试题最新pdf版,请搜索公众号[五分钟学大数据],对话框发送 面试宝典 扫码获取最新PDF版: 版本 时间 描述 V1.0 2020-02-18 ...

  3. 大数据面试吹牛草稿V2.0

    面试吹牛之前先打个草稿! 本文首发于微信公众号[五分钟学大数据],公众号上有很多大数据学习方法,学习文档,最全的大数据面试八股文等 各位面试官好! 1. 我叫 xxx,毕业于 xxx,之前在 xxx ...

  4. 常见大数据面试话术(建议收藏)

    点击上方 "大数据肌肉猿"关注, 星标一起成长 后台回复[加群],进入高质量学习交流群 2021年大数据肌肉猿公众号奖励制度 面试吹牛之前先打草稿! 各位面试官好! 我叫 xxx, ...

  5. 精选大数据面试真题10道(附答案详细解析)

    大数据笔面试系列文章分为两种类型:混合型(即一篇文章中会有多个框架的知识点-融会贯通):专项型(一篇文章针对某个框架进行深入解析-专项演练). 此篇文章为系列文章的第一篇(混合型) 第一题:大数据笔试 ...

  6. 大数据面试之新浪面试题

    大数据面试之新浪面试题 学长1 一面 1)自我介绍 叫什么名字,来自哪里,本科哪个学校,硕士哪个学校,大数据做了多长时间,对Hadoop生态圈以及Spark生态圈中的哪些技术比较了解(很简单的一句就带 ...

  7. 大数据面试3分钟自我介绍_大数据面试要注意哪些方面?大数据面试准备三大攻略...

    大数据面试要注意哪些方面?一般来说,求职者要做好自我介绍.面试提问和专业考题三大方面的准备.下面是小编专门为大数据求职者整理的面试攻略,希望对大家找工作有所帮助. 一.大数据面试的自我介绍. 面试一开 ...

  8. 面试系列一:精选大数据面试真题10道(混合型)-附答案详细解析

    本公众号(五分钟学大数据)将推出大数据面试系列文章-五分钟小面试,此系列文章将会深入研究各大厂笔面试真题,并根据笔面试题扩展相关的知识点,助力大家都能够成功入职大厂! 大数据笔面试系列文章分为两种类型 ...

  9. 大数据面试求职经验总结

    写在前面:空杯心态,多投多改,把握好校招机会,它是你最容易通往大厂的机会. 面试经验分享: 1. 提前了解应聘公司信息,知道该公司是做什么的,发展情况,招聘的岗位的要求等 : 2.面试不要说自己是培训 ...

  10. python人工智能面试题爱奇艺面试题_【爱奇艺Python面试】爱奇艺大数据面试 python-看准网...

    爱奇艺大数据面试 python 通知的今天上午11点爱奇艺一轮面试,今天!周末!周末!周末!竟然还要面试,内心很无语,上个星期人家腾讯还是周一面试呢,但是,想想宿舍的一个小伙伴今天上午9点半的面试,庆 ...

最新文章

  1. 从零开始学习PYTHON3讲义(一)认识Python
  2. 把两个salmon和sea bass特征结合起来能够提高区分的准确率
  3. 清华开学,713分寒门学霸揭露一个真相:别抱怨读书苦,那是你看世界的路
  4. 川大计算机生物学怎么样,四川大学生物信息学初试经验分享
  5. [Java] 蓝桥杯BASIC-16 基础练习 分解质因数
  6. UI:使用 pod 引入 AFNetworking
  7. python入门经典100题-零基础学习Python开发练习100题实例(1)
  8. 当你想对常用网站定制属于自己的颜色,然而又没人理你怎么办
  9. Sublime中使用livereload插件实时预览html文件
  10. 小米笔记本Pro 黑苹果10.15.2记录 不需要焊接,完美支持airdrop、接力、随航
  11. 【机器学习】信息熵基础学习
  12. 禅道开源版用户手册_禅道的安装与使用指南
  13. 软件观念革命:交互设计精髓_UI设计师、交互设计师、产品经理必备软件技能之Sketch...
  14. w7计算机摄像头怎么打开,如何打开摄像头,详细教您Win7摄像头怎么打开
  15. 海报与Banner的区别
  16. 亚马逊海外购SAMSUNG 三星T7上手初体验
  17. 浏览器下载文件,读取BLOB字段会因为数据太大导致数据库连接connect超时关闭的解决方案...
  18. python opencv图像阈值处理
  19. 【深度学习】CNN与RNN有什么不同?
  20. Python:读取 csv 文件并插入到 PostgreSQL 数据库

热门文章

  1. ES(四)ES使用(基本查询、聚合查询)
  2. 杨百翰大学 排名Brigham Young University,入学要求,申请条件,简介_施强留学网...
  3. aardio设置透明窗体说明
  4. easyui api添加html,Easyui 扩展编辑器_EasyUI 教程
  5. 泛泛而谈的菜鸟学习记录(六)—— 贴花
  6. ArcGIS Server 发布服务失败
  7. iOS描述文件(.mobileprovision)一键申请
  8. 听说根域名大部分在美国,美国能让中国从网络上消失?
  9. 26367411153598389kygoq
  10. ORACLE获取月初、月末日期