SQL-计算留存率cohort

news2024/11/23 8:58:48

目录

1、留存率cohort介绍及其业务价值

2、计算思路

3、实操

3.1、日对日留存cohort

3.2、周对周留存cohort

3.3、月对月留存cohort


1、留存率cohort介绍及其业务价值

留存率cohort也叫做同期群留存分析,将同一时间范围内的用户分为一组,计算这批人在之后的留存情况,一般结果的样式如下(这里省略数值,):

新增留存

日期新增客户数次1日留存次2日留存次3日留存....
20220101100050%40%39%
2022010298159%50%
2022010381961%

老客留存(数据略)

日期老客户数次1留存次2留存次3留存....

根据留存cohort图可以得到两方面的信息

1、从横向看,可以得到一批用户在长时间范围内的衰减情况

以上述示例来看:用户在新增后的前两天是快速衰减的(第一天之后有50%的用户不再来了,第三天又损失了40%),到第四天会逐步稳定下来,可见前三天是产品抓住用户的关键窗口期。

2、从纵向看,可以看出不同时间周期来的用户,他们的留存情况是否有改善

以上述示例来看:用户的次日留存在逐步改善(从50%-59%-61%)这可能是产品上做了优化调整,也可能是投放侧在用户的选择上更精准了(对应的用户新增数量也在减少)

2、计算思路

如果通过SQL得到留存cohort数据呢?

Step1:计算留存率分母数据,即每日的用户量

通常来说,新老用户的留存率差异是非常大的,所以需要进行区分。有现成的用户标签是最好的,如果没有可以用窗口函数计算用户是第几次来,第一次来的用户就是当日新增用户。

step2:计算留存率分子

这里计算的间隔时间可以是日,周,月各种时间粒度

关于SQL时间计算的相关知识点可以参考:

SQL-时间处理汇总_格勒王的博客-CSDN博客常见日期提取,日期格式转换,日期加减计算等时间处理方法汇总https://blog.csdn.net/weixin_47198715/article/details/130823960?spm=1001.2014.3001.5502

日期间隔时间留存客户数
202201011500
202201012400
202201013390
20220102......

step3:将上面两步骤数据合并

3、实操

3.1、日对日留存cohort

with tmp as 
(select 
  date,--yyyy-mm-dd格式,如果是yyyymmdd需要转换
  user_id
from table_name
where is_new=1#筛选新用户
)


select 
a.date,
gap,
`客户数`,
`留存客户数`,
round(`留存客户数`/`客户数`,2) as `留存率`
from 
 (--计算留存率分母
    SELECT DATE,COUNT(DISTINCT user_id) AS `客户数`
  FROM  tmp
  GROUP BY DATE)a--计算每日新增客户数
LEFT JOIN 
 (--计算留存率分子
  SELECT
  begin_date,
  gap,
  count(distinct user_id) as `留存客户数`
  from 
    (SELECT
    a.user_id,
    a.date as begin_date,
    b.date as stay_date,
    datediff(b.date,a.date)as gap--计算间隔天数
    from 
      (select *
      from tmp)a
    left join 
      (select *
      from tmp)b
    on a.user_id=b.user_id)a
    where gap>=1--筛选间隔天数大于等于1的记录
  group by begin_date,gap)b
on a.date=b.begin_date

3.2、周对周留存cohort

和日对日留存的区别在于,日对日留存只需要计算两次日期的间隔天数即可

而周对周的留存需要计算两个日期的间隔周

有两种方法可以实现周对周留存率的计算

1、先把每天的日期对应到当周的周一,再计算周一之间的日期差除以7

2、使用weekofyear函数,但是这里如果涉及到跨年,需要在处理的时候注意

weekofyear('yyyy-mm-dd')

两个日期周数相差:公式:(52-新增周)+(留存日年份-新增日年份)*留存日周数

如2022年第51周新增的用户,在2023年第1周的留存,计算两个日期的周数差:

(52-51)+(2023-2022)*1=2(也就是次2周留存)

我们以第一种方法示例


with tmp as 
(select 
  date,--yyyy-mm-dd格式,如果是yyyymmdd需要转换
  date_add(DATE,2-if(dayofweek(DATE)=1,8,dayofweek(DATE))) as monday,
  user_id
from table_name
where is_new=1#筛选新用户
)


select 
a.monday,
gap,
`客户数`,
`留存客户数`,
round(`留存客户数`/`客户数`,2) as `留存率`
from 
 (--计算留存率分母
    SELECT monday,COUNT(DISTINCT user_id) AS `客户数`
  FROM  tmp
  GROUP BY monday)a--计算每日新增客户数
LEFT JOIN 
 (--计算留存率分子
  SELECT
  begin_date,
  gap,
  count(distinct user_id) as `留存客户数`
  from 
    (SELECT
    a.user_id,
    a.monday as begin_week,
    b.monday as stay_week,
    datediff(b.monday,a.monday)/7 as gap--计算间隔周数
    from 
      (select *
      from tmp)a
    left join 
      (select *
      from tmp)b
    on a.user_id=b.user_id)a
    where gap>=1--筛选间隔天数大于等于1的记录
  group by begin_date,gap)b
on a.monday=b.begin_week

3.3、月对月留存cohort

计算两个日期之间的月份差可以使用month_bvetween(date1,date2)函数,但是这里计算出来的月份差非整数,如20230301和20230430之间的月份差也是1

在计算月留存时,我们需要对其向下取整,即floor(month_bvetween(date1,date2))

with tmp as 
(select 
  date,--yyyy-mm-dd格式,如果是yyyymmdd需要转换
  substr(DATE,1,7) AS month,
  user_id
from table_name
where is_new=1#筛选新用户
)


select 
a.month,
gap,
`客户数`,
stay_num
from 
 (--计算留存率分母
    SELECT month,COUNT(DISTINCT user_id) AS `客户数`
  FROM  tmp
  GROUP BY month)a--计算每日新增客户数
LEFT JOIN 
 (--计算留存率分子
  SELECT
  begin_date,
  gap,
  count(distinct user_id) as `留存客户数`
  from 
    (SELECT
    a.user_id,
    a.month as begin_month,
    floor(months_between(b.date,a.date))as gap--计算间隔天数
    from 
      (select *
      from tmp)a
    left join 
      (select *
      from tmp)b
    on a.user_id=b.user_id)a
    where gap>=1--筛选间隔天数大于等于1的记录
  group by begin_month,gap)b
on a.month=b.begin_month

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

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

相关文章

Linux命令(26)之uptime

Linux命令之uptime 1.uptime介绍 linux命令uptime是用来为用户提供系统从开启到当前运行uptime命令时系统已运行的时长信息,除此之外,还提了系统启动时间,当前登录用户,系统平均负载信息。 2.uptime用法 uptime [参数] uptime…

华为OD机试真题(Java),四则运算(100%通过+复盘思路)

一、题目描述 输入一个表达式(用字符串表示),求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。 数据范围:表达…

gitlab记录

1、docker方式部署启动 参考文档: https://blog.csdn.net/weixin_53443677/article/details/125518696 https://blog.csdn.net/weixin_39034012/article/details/119211630 1.1、docker启动gitlab 前期准备 > # 拉镜像 > docker pull gitlab/gitlab-ce:late…

chatgpt赋能python:Python代码30行:提高网站SEO的最佳实践

Python 代码 30 行:提高网站 SEO 的最佳实践 搜索引擎优化(SEO)是网站成功的重要因素,它可以让网站排名更高并吸引更多的流量。Python 代码可以帮助您实现最佳的 SEO 实践,并提高网站的可见性和排名。下面是一个包含 …

Tugraph的设计和源码初步解析

1. Tugraph Tugraph是一款开源的性能优秀的图数据库,该图数据库使用多版本的BTree作为数据的存储引擎,同时设置了点边数据在这个存储引擎上的布局(主要考虑数据的局部性),从而达到高性能查询的目的。本文主要从Tugrap…

ubuntu系统登录密码重置方法

公司搬家,需要更改git服务器地址,发现服务器密码也忘记了,折腾了下,通过如下方法修改成功。 一、重启计算机并进入GRUB菜单(如果您的计算机没有显示GRUB菜单,请尝试按住Shift键或Esc键,直到出现…

手机安卓Termux搭建Hexo博客网站,并发布公网访问。

文章目录 1. 安装 Hexo2. 安装cpolar内网穿透3. 公网远程访问4. 固定公网地址 转载自cpolar极点云的文章:安卓手机使用Termux搭建Hexo个人博客网站【内网穿透公网访问】 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#…

DAY04_JDBC快速入门JDBC API详解SQL防注入数据库连接池JDBC综合练习

目录 1 JDBC1.1 JDBC概念1.2 JDBC本质 1.3 JDBC好处 2 JDBC快速入门2.1 编写代码步骤2.2 具体操作 3 JDBC API详解3.1 DriverManager3.2 Connection3.2.1 获取执行对象3.2.2 事务管理 3.3 Statement3.4 ResultSet3.4.1 ResultSet案例 3.5 PreparedStatement3.5.1 SQL注入3.5.2 …

基于opencv实现两路yuv数据拼接合成一张大图

背景 实时音视频通话(RTC)越来越注重安全审核,特别是在1v1娱乐社交场景中,对于视频反垃圾的需求也越来越大。随之而来的是客户对审核成本降低的诉求日益强烈。针对1v1场景,将两路视频拼接成一张图片进行审核相比于分别…

大数据Doris(三十一):Broker Load导入HDFS json格式数据和注意事项

文章目录 Broker Load导入HDFS json格式数据和注意事项 一、导入HDFS json格式数据 1、创建Doris表

nginx(八十一)rewrite模块指令再探之(三)重定向

一 return和rewrite重定向再探 ① 前言 多种重定向跳转方式的差异 nginx与Location响应头细节探讨 本为不涉及讨论如下的绝对重定向1) return 301 http://www.wzj.com:6443/url?namewzj2) rewrite ... http://www.wzj.com:6443/url 2) rewrite ... http://www.wzj.com:64…

一分钟学一个 Linux 命令 - pwd

前言 大家好,我是 god23bin。欢迎大家继续围观《一分钟学一个 Linux 命令》,每天只需一分钟,记住一个 Linux 命令不成问题。本篇文章将聚焦于 pwd 命令,一个超级简单又常用的命令。在接下来的内容中,我将快速介绍 pwd…

Elasticsearch总结

详细描述一下 Elasticsearch 搜索的过程? 1、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch; 2、在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执…

chatgpt赋能python:使用Python关闭所有子进程

使用Python关闭所有子进程 如果您使用Python编写了多进程应用程序,那么您可能会遇到一些关闭所有子进程的问题。这种情况可能是您的主进程已经完成了,但是子进程却没有关闭,从而导致资源浪费和程序崩溃。在这篇文章中,我们将讨论…

STM32F1xx -- Systick 系统滴答定时器

1. SysTick 是一个向 CPU 提供定时中断信号的计数器,其计数速率是由 Cortex-M 系列处理器的系统时钟频率和 SysTick 计数器的重载值共同决定的。 1.1 Systick 时钟来源之一,Systick 一般设置为1ms 中断一次,为系统任务调度提供服务&#xff…

R语言:集卡活动概率测算模拟

背景:以支付宝集五福活动为代表的集卡类营销活动背后,每张卡出现的概率测算是非常重要的,假设我们可以预估有多少人参与活动以及大致每人能抽多少次,且限定一共有多少人能够集齐,在这些限定条件下,每张卡出…

CentOS 系统上安装 Jenkins

#######################注意我这里安装jenkins版本要求实际是要安装jdk11版本的~~~我一开始弄错了 您可以按照以下步骤在 CentOS 上安装 JDK: 1. 首先,打开终端并使用 yum 命令更新系统软件包列表。输入以下命令来执行此操作: sudo yu…

chatgpt赋能python:Python为什么闪退?

Python为什么闪退? Python作为一种高级编程语言,已经赢得了世界各地许多开发者的青睐。但是,有时候Python会因为各种原因而突然闪退,给开发者带来极大的困扰。那么,Python为什么会闪退呢? 1. 内存泄漏 内…

环境感知算法——2.CenterNet基于KITTI数据集训练

1. CenterNet简介 CenterNet采用了一种新的检测思路,即以目标中心点为基础,直接回归出目标的位置和大小。而传统的目标检测算法通常会先产生大量候选框(Anchor),再通过分类器进行筛选,这种方法比较复杂。C…

selenium浏览器自动化测试

Selenium是一个用于Web应用程序的自动化测试工具。它直接运行在浏览器中,可以模拟用户在浏览器上面的行为操作。 Selenium入门 下载驱动 查看谷歌浏览器版本 谷歌浏览器输入网址的地方输入:chrome://version 下载与浏览器对应(或相近&#x…