留存率的定义与SQL实现

news2024/10/2 16:51:23

1.什么是留存率

留存率是指在特定时间段内,仍然继续使用某项产品或服务的用户占用户总数的百分比。

通常,留存率会以日,周,或月为单位进行统计和分析。

2.SQL留存率常见问题

1.计算新用户登录的日期的次日留存率以及3日留存率

CREATE TABLE ods_user_login_log (
    user_id VARCHAR(255) NOT NULL,
    login_dt VARCHAR(255) NOT NULL
);
INSERT INTO ods_user_login_log VALUES 
('001','20240701'),
('001','20240701'),
('002','20240701'),
('003','20240701'),
('001','20240702'),
('002','20240702'),
('002','20240702'),
('001','20240703'),
('002','20240704'),
('004','20240704')
;

有一张用户登录日志表 ods_usr_login_log,包含 user_id(用户ID)和 login_dt(登录日期)。每个用户在同一天可能登录多次。

问题:计算有新用户登录的日期的次日留存率和3日留存率。

N日留存用户数:指某日活跃的用户在第N日再次活跃的用户数量。

对这道题,我们要先确定新用户登录的日期,也就是用户首次登录的日期。

由于每个用户在同一天可能登录多次,但实际上我们只需保留该用户当天的一条数据,所以我们可以使用 distinct去重。

如何计算留存间隔?

 通过计算datediff(end_time, start_time)来确定日期间隔。

所以,本道题思路如下:

  1. 找出每个用户首次登录的日期

    使用子查询 t1,通过 MIN(login_dt) 函数获取每个用户的首次登录日期,并将其转换为日期格式 date
  2. 将所有登录记录转换为日期格式

    子查询 t2 将 login_dt 字段转换为日期格式,并保留每个用户每一天的登录记录。
  3. 计算次日留存率和3日留存率

    • 在最终的 SELECT 语句中,使用 DATEDIFF(t2.dt, t1.dt) 来计算用户登录日期与其首次登录日期的天数差。
    • 对于次日留存率,当天数差为1时,使用 COUNT(DISTINCT t2.user_id) 统计次日再次登录的用户数量,并将其除以首次登录的用户数量 COUNT(DISTINCT t1.user_id),得到次日留存率。
    • 对于3日留存率,类似地,当天数差为3时,计算第3日再次登录的用户数,并进行相应的计算。
  4. LEFT JOIN 进行多表联查

为什么使用LEFT JOIN?
LEFT JOIN 的作用是保留左表中的所有记录(即使在右表中没有匹配项)。在这个SQL语句中,左表是子查询 t1,它包含每个用户的首次登录日期。右表是 t2,它包含用户的所有登录记录。通过 LEFT JOIN,我们可以确保所有首次登录的用户都会出现在最终的结果中,即使这些用户在后续的指定日期(如次日或第3日)没有再次登录。这样可以保证在计算留存率时,所有首次登录的用户都被纳入分母,即使他们在后续日期没有登录,确保留存率计算准确无误。

一分钟搞明白Join、Left Join、Right Join的区别_join left join right join-CSDN博客

-- 计算用户首次登录的日期
with t1 as (
  select  
     user_id,
     cast(min(login_dt) as date) as dt
     from ods_user_login_log
  group by user_id, cast(login_dt as date)
),
-- 将数据转为date格式
t2 as (
  select 
    user_id, cast(login_dt as date) as dt
  from ods_user_login_log
  group by user_id, cast(login_dt as date) 
)

select 
  t1.dt
  -- 确保用户在同一天登录的数据只被计算一次
,count(distinct case when datediff(t2.dt, t1.dt) = 1 then t2.user_id else null end) 
  / count(distinct t1.user_id) as retain_1d_rate
,count(distinct case when datediff(t2.dt, t1.dt) = 3 then t2.user_id else null end) 
 / count(distinct t1.user_id) as retain_3d_rate
from t1
left join t2
on t1.user_id = t2.user_id
group by t1.dt
;

2.2021年11月每天新用户的次日留存率_牛客题霸_牛客网

在本道题中,我们同样是计算新用户的次日留存率。

但数据列却完全不同,第一道题中,我们的数据列就只有登录时间。

在本题中,我们既有in_time进入时间,又有离开时间out_time。

那么就会存在一个情况:当在一条记录中,如果in_time-进入时间和out_time-离开时间跨天了。

如:(101, 9002, '2021-11-04 11:00:55', '2021-11-05 11:00:59', 0);

这时我们也算该用户在两天里都活跃过

那么,我们该如果计算,才能实现该逻辑呢?

具体来说,就是将in_time和out_time合并为同一个数据列,记录每个用户在每天的活跃情况。

select uid, date(in_time) as active_dt from tb_user_log
   union all
select uid, date(out_time) as active_dt from tb_user_log

具体来说,我们就是把out_time也算作是活跃日。

在这里我们使用UNION ALL,是因为:

  • 它可以保留所有的用户行为记录,包括重复的日期。这对于准确计算次日留存率很重要。
  • 我们需要考虑每个用户可能在同一天多次访问的情况。使用 UNION ALL 确保了我们捕获到所有这些访问记录。(然后distinct去重)

剩下的操作就跟第一道题一样,计算用户首次登录的日期,然后通过计算datediff(end_time, start_time)来确定日期间隔。

with t1 as (
    select 
    uid,
    min(in_time) as dt
    from 
    tb_user_log
    group by uid
),
t2 as (
    select uid, date(in_time) as active_dt from tb_user_log
    union all
    select uid, date(out_time) as active_dt from tb_user_log
)
    select 
     date_format(t1.dt,'%Y-%m-%d') as dt,
     round(count(distinct case when datediff(t2.active_dt,t1.dt) = 1 then t2.uid else null end) /
     count(distinct t1.uid),2) as uv_left_rate
     from t1
     left join t2
     on t1.uid = t2.uid
     where date_format(t1.dt,'%Y-%m') = '2021-11'
     -- t1.dt BETWEEN '2021-11-01' AND '2021-11-30'
     group by date_format(t1.dt,'%Y-%m-%d')

优化小建议:

使用 DATE_FORMAT(t1.dt, '%Y-%m') = '2021-11' 进行筛选,这样的条件会在查询时对所有结果再次进行格式化,可能会影响性能。 (格式化 + 筛选)

使用 t1.dt BETWEEN '2021-11-01' AND '2021-11-30' 进行时间范围过滤,这样的条件可以利用之前已经格式化好的数据,性能更好。 (只有筛选)

20230724024159.png?origin_url=chrome-extension%3A%2F%2Fpbhpcbdjngblklnibanbkgkogjmbjeoe%2Fsrc%2Fpublic%2Fimages%2F128px.png&pos_id=htfBsUYu)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2184733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【鸿蒙学习】深入了解UIAbility组件

文章目录 组件概述生命周期启动模式基本用法 在鸿蒙操作系统(HarmonyOS)的开发过程中,UIAbility组件是构建应用界面的关键。本文将带您了解UIAbility组件的概述、生命周期、启动模式以及基本用法,并通过代码示例帮助您更好地掌握这…

微信互助学习平台|互助学习平台系统|基于java的微信互助学习平台设计与实现(源码+数据库+文档)

微信互助学习平台 目录 基于java的微信互助学习平台设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师…

论文阅读- On the Feasibility of Fully AI-automated Vishing Attacks

https://arxiv.org/pdf/2409.13793 目录 摘要 INTRODUCTION II. GOALS AND THREAT MODEL III. VIKING A. Architecture B. Interaction with the LLM C. Audio processing D. Call processing E. Implementation IV. EVALUATION METHODOLOGY A. Experiment design …

NeRF三维重建—神经辐射场

NeRF—神经辐射场 本文介绍了三维重建相关技术,特别是神经辐射场(NeRF)的进步,它通过深度学习实现逼真的三维场景重建。NeRF在计算机图形学、自动驾驶和元宇宙等领域展现出广阔的应用前景,通过改进传统方法,提供更高质量的渲染和沉…

聊聊国内首台重大技术装备(1)

9.9日,工信部发布了《首台(套)重大技术装备推广应用指导目录(2024年版)》,在集成电路领域,公布了如下首台机台设备,这确实是一个十分振奋人心的消息,说明我国在半导体制造…

LSTM模型实现光伏发电功率的预测

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝,拥有2篇国家级人工智能发明专利。 社区特色…

构造函数继承

构造函数继承 主要通过在子类的构造函数中调用父类的构造函数,绑定子类实例的 this,从而实现子类对父类属性的继承。这种方法避免了父类和子类共享原型链上的属性,并且可以传递参数给父类的构造函数。 构造函数继承的实现步骤: …

Windows远程Kylin系统-VNC

Windows远程Kylin系统-VNC 一. 配置 yum源 二. 清理yum缓存 三. 安装VNC并配置 nkvers yum install tigervnc tigervnc-server -ycp /lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:1.service 说明:vncserver:1.service中的:1表…

Windows 环境下安装 Anaconda 并适配到 PowerShell 的保姆级教程

Anaconda Anaconda 是一个流行的 Python 数据科学和机器学习平台,它包括了 Conda 包管理器、Python 以及数百个用于科学计算的库和工具。Anaconda 旨在简化包和环境管理,使得安装、更新和管理软件包变得容易,同时也能够轻松创建和切换不同的P…

案例-百度热榜页面实现

文章目录 效果展示要求内容注意代码内容 效果展示 要求内容 整个盒子大小:536*536标题字体柜20px、加粗,纯黑,换一换字体大小20px、颜色0055db、刷新图标是本地图片内容字体18px、上下边距15px、下边框实心2px颜色f3f3f3这个需要根据页面显示…

【顺序查找】

目录 一. 顺序查找的概念二. 查找的性能计算 \quad 一. 顺序查找的概念 \quad \quad 二. 查找的性能计算 \quad

【LLM论文日更】| 通过指令调整进行零样本稠密检索的无监督文本表示学习

论文:https://arxiv.org/pdf/2409.16497代码:暂未开源机构:Amazon AGI、宾夕法尼亚州立大学领域:Dense Retrieval发表:Accepted at DCAI24 workshopCIKM2024 研究背景 研究问题:这篇文章要解决的问题是如…

Linux学习笔记(三):文件管理、复杂操作与实用工具详解

Linux学习笔记(三):文件管理、复杂操作与实用工具详解 Linux 学习笔记(二):深入理解用户管理、运行级别与命令行操作 1.文件操作的基本操作 1.1 创建 创建目录 mkdir:创建目录 mkdir /home/d…

【MySQL】多表联合查询常见练习题

数据库表如下: teacher:老师表 course:课程表 student:学生表 class:班级表 sc:成绩表 一、根据上面5张表写sql语句 1. 查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数 select student.…

AI智能时代的图书馆未来,你想象过吗!

AI智能时代的图书馆未来,你想象过吗! 前言AI智能时代的图书馆未来 前言 教育数字化和 AI 时代的浪潮正汹涌而来,图书馆也站在了变革的十字路口。我们看到高等教育正在发生深刻的变革,从教学模式到人才培养理念,都在经…

基于SSM+VUE的学生宿舍管理系统

文未可获取一份本项目的java源码和数据库参考。 随着社会经济的迅速发展和科学技术的全面进步,计算机事业的飞速发展,以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期,当今社会正快速向数字化,信息化,网络化…

VSCode开发Vue3+TS项目中遇到各种波浪线(诊断信息)

一、问题汇总 在使用Visual Studio Code(VSCode)开发Vue3 TypeScript项目时,会遇到各种波浪线错误(诊断信息),这些问题或错误通常由以下几人原因引起的: 1.1 常见问题 1、typeScript配置问题…

【探索 GDB 和 CGDB】:强大的调试工具介绍

📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 1. 引言📃 1.1 …

Kotlin:1.8.0 的新特性

一、概述 Kotlin 1.8.0版本英语官方文档 Kotlin 1.8.0 中文官方文档 The Kotlin 1.8.0 release is out and here are some of its biggest highlights: Kotlin 1.8.0发布了,下面是它的一些亮点: JVM 平台新增实验性函数:递归复制或删除目录内容改进了 …

SpringMVC——REST

路径请求方式请求行为 查询:GET 新增:POST 修改:PUT 删除:DELETE 有重复的东西怎么办