当前位置: 首页 > news >正文

SQL面试题2:留存率问题

引言

场景介绍:

在互联网产品运营中,用户注册量和留存率是衡量产品吸引力和用户粘性的关键指标,直接影响产品的可持续发展和商业价值。通过分析这些数据,企业可以了解用户行为,优化产品策略,提升用户体验。

题目描述:

假设有一个记录用户注册信息表 reg_tb,包含两个字段:uid(用户ID)和reg_dt(用户注册日期)。同时,还有一个记录用户登录行为表login_tb,包含两个字段:uid(用户ID)和login_dt(用户登录日期)。现在,你需要完成以下任务:

  1. 计算次日留存率。即,1月1日注册的用户,1月2日登录的比例是多少。比如今天有 100 个用户注册,明天有 20 个这些注册过的用户又登录了,那次日留存率就是 20% 。这个指标能反映出产品对新用户的初步吸引力。
  2. 计算三日留存率。即今天(1月1日)注册的用户,在第三天(1月4日)还会登录的比例。
  3. 计算七日留存率。通过这两个指标,了解新用户经过一段时间后,对产品的持续参与度如何。

数据准备与代码实现

数据准备

CREATE TABLE reg_tb (uid INT,regdt DATE
);INSERT INTO reg_tb VALUES
(1, '2025-01-01'),
(2, '2025-01-01'),
(3, '2025-01-02'),
(4, '2025-01-02'),
(5, '2025-01-02');
CREATE TABLE login_tb (uid INT,logindt DATE
);INSERT INTO login_tb VALUES
(1, '2025-01-02'),
(1, '2025-01-03'),
(2, '2025-01-03'),
(2, '2025-01-04'),
(3, '2025-01-03'),
(3, '2025-01-05'),
(4, '2025-01-05'),
(5, '2025-01-09');

如图所示,红色为次日登录,黄色为第三日登录,紫色为第七日登录。
在这里插入图片描述

1. 计算次日留存率

步骤:

  1. 利用left join将 reg_tb 表和 login_tb 表进行左连接,保证 reg_tb 表中的所有记录都会出现,连接条件是uid 相等,且 login_tb 表中的登录日期 logindt 是 reg_tb 表中注册日期 regdt 加 1 天,这样可以找到在注册后第二天登录的用户。
  2. COUNT(DISTINCT l.uid)统计在 login_tb 表中与 reg_tb 表通过 LEFT JOIN 连接后满足条件的不重复的 uid 的数量。COUNT(DISTINCT r.uid) :统计 reg_tb 表中的不重复的 uid 的数量,两者相除计算次日留存率。

注意点:由于count()在left join情况下,当没有匹配的登录记录时,l.uid 会是 NULL ,但 count() 会将其作为计数的一部分。因此,应使用count(distinct l.uid)代替count(l.uid)使得结果更加准确。

select count(distinct l.uid)/count(distinct r.uid) rrd1
from reg_tb r
left join login_tb l on r.uid = l.uid and l.logindt = date_add(r.regdt,1);

优化:将结果以百分比的形式显示四舍五入到一位小数

select ROUND(COUNT(DISTINCT l.uid) / COUNT(DISTINCT r.uid) * 100, 1) || '%' AS rrd1
from reg_tb r
left join login_tb l on r.uid = l.uid and l.logindt = date_add(r.regdt,1);

2. 次日、三日、七日留存率

select ROUND(COUNT(DISTINCT l1.uid) / COUNT(DISTINCT r.uid) * 100, 1) || '%' AS rrd1,ROUND(COUNT(DISTINCT l3.uid) / COUNT(DISTINCT r.uid) * 100, 1) || '%' AS rrd3,ROUND(COUNT(DISTINCT l7.uid) / COUNT(DISTINCT r.uid) * 100, 1) || '%' AS rrd7
from reg_tb r
left join login_tb l1 on r.uid = l1.uid and l1.logindt = date_add(r.regdt,1)
left join login_tb l3 on r.uid = l3.uid and l3.logindt = date_add(r.regdt,3)
left join login_tb l7 on r.uid = l7.uid and l7.logindt = date_add(r.regdt,7);

在这里插入图片描述

http://www.lryc.cn/news/521098.html

相关文章:

  • 晨辉面试抽签和评分管理系统之九:随机编排考生的分组(以教师资格考试面试为例)
  • 【EtherCATBridge】- KRTS C++示例精讲(9)
  • C++实现设计模式--- 观察者模式 (Observer)
  • iOS 解决两个tableView.嵌套滚动手势冲突
  • Lianwei 安全周报|2025.1.13
  • rtthread学习笔记系列(2) -- 宏
  • 美摄科技PC端视频编辑解决方案,为企业打造专属的高效创作平台
  • 服务端开发模式-thinkphp-重新整理workman
  • HTB:Access[WriteUP]
  • 【论文笔记】SmileSplat:稀疏视角+pose-free+泛化
  • 电机控制的数字化升级:基于DSP和FPGA的仿真与实现
  • 1/14 C++
  • java springboot3.x jwt+spring security6.x实现用户登录认证
  • YOLOv5训练长方形图像详解
  • 【2025最新】Poe保姆级订阅指南,Poe订阅看这一篇就够了!最方便使用各类AI!
  • type1-100,2 words
  • Leetcode 377. 组合总和 Ⅳ 动态规划
  • 计算机网络(五)——传输层
  • 【SQL】进阶知识 -- 删除表的几种方法(包含表内单个字段的删除方法)
  • 【搭建JavaEE】(3)前后端交互,请求响应机制,JDBC数据库连接
  • 项目概述、开发环境搭建(day01)
  • 车联网安全--TLS握手过程详解
  • 【python】OpenCV—Extract Horizontal and Vertical Lines—Morphology
  • Redis十大数据类型详解
  • Open FPV VTX开源之betaflight配置
  • AT32 bootloader程序与上位机程序
  • 数据结构与算法之栈: LeetCode 151. 反转字符串中的单词 (Ts版)
  • 使用 configparser 读取 INI 配置文件
  • idea 自动导包,并且禁止自动导 *(java.io.*)
  • RK3588-NPU pytorch-image-models 模型编译测试