SQL计算复购率

2023-11-13

需求背景:
订单表中有每笔订单的下单时间、用户ID、订单金额等信息,需要统计每个月在接下来几个月用户复购情况。

create table order_info(
order_id int primary key,
user_id int,
amount decimal(10,2),
create_time datetime
);

insert into order_info values
(101,11211,749.00,'2020-01-01 00:04:00'),
(102,75205,939.00,'2020-01-05 09:15:00'),
(103,81384,349.00,'2020-01-08 22:19:00'),
(104,50437,687.00,'2020-01-11 22:17:00'),
(105,30321,658.00,'2020-01-12 22:18:00'),
(106,49811,355.00,'2020-01-16 22:18:00'),
(107,30352,363.00,'2020-01-19 22:24:00'),
(108,30362,435.00,'2020-01-22 22:18:00'),
(109,30363,270.00,'2020-01-27 22:19:00'),
(110,30324,552.00,'2020-01-30 22:22:00'),
(111,11211,692.00,'2020-02-04 08:35:00'),
(112,75205,536.00,'2020-02-09 11:03:00'),
(113,81384,478.00,'2020-02-13 09:32:00'),
(114,30362,675.00,'2020-02-17 11:18:00'),
(115,30363,723.00,'2020-02-20 08:47:00'),
(116,30324,914.00,'2020-02-21 10:48:00'),
(117,49262,444.00,'2020-02-24 18:35:00'),
(118,12074,617.00,'2020-02-29 20:16:00'),
(119,50437,911.00,'2020-03-02 12:35:00'),
(120,30321,695.00,'2020-03-14 23:53:00'),
(121,12074,275.00,'2020-03-15 15:38:00'),
(122,81384,1066.00,'2020-03-18 16:49:00'),
(123,30362,431.00,'2020-03-23 09:01:00'),
(124,27727,687.00,'2020-03-25 15:38:00'),
(125,27727,858.00,'2020-03-28 17:44:00');

select * from order_info;
+----------+---------+---------+---------------------+
| order_id | user_id | amount  | create_time         |
+----------+---------+---------+---------------------+
|      101 |   11211 |  749.00 | 2020-01-01 00:04:00 |
|      102 |   75205 |  939.00 | 2020-01-05 09:15:00 |
|      103 |   81384 |  349.00 | 2020-01-08 22:19:00 |
|      104 |   50437 |  687.00 | 2020-01-11 22:17:00 |
|      105 |   30321 |  658.00 | 2020-01-12 22:18:00 |
|      106 |   49811 |  355.00 | 2020-01-16 22:18:00 |
|      107 |   30352 |  363.00 | 2020-01-19 22:24:00 |
|      108 |   30362 |  435.00 | 2020-01-22 22:18:00 |
|      109 |   30363 |  270.00 | 2020-01-27 22:19:00 |
|      110 |   30324 |  552.00 | 2020-01-30 22:22:00 |
|      111 |   11211 |  692.00 | 2020-02-04 08:35:00 |
|      112 |   75205 |  536.00 | 2020-02-09 11:03:00 |
|      113 |   81384 |  478.00 | 2020-02-13 09:32:00 |
|      114 |   30362 |  675.00 | 2020-02-17 11:18:00 |
|      115 |   30363 |  723.00 | 2020-02-20 08:47:00 |
|      116 |   30324 |  914.00 | 2020-02-21 10:48:00 |
|      117 |   49262 |  444.00 | 2020-02-24 18:35:00 |
|      118 |   12074 |  617.00 | 2020-02-29 20:16:00 |
|      119 |   50437 |  911.00 | 2020-03-02 12:35:00 |
|      120 |   30321 |  695.00 | 2020-03-14 23:53:00 |
|      121 |   12074 |  275.00 | 2020-03-15 15:38:00 |
|      122 |   81384 | 1066.00 | 2020-03-18 16:49:00 |
|      123 |   30362 |  431.00 | 2020-03-23 09:01:00 |
|      124 |   27727 |  687.00 | 2020-03-25 15:38:00 |
|      125 |   27727 |  858.00 | 2020-03-28 17:44:00 |
+----------+---------+---------+---------------------+

解析思路:
第一步:查询每个月下过单的用户

select month(create_time) as dt,user_id 
from order_info 
group by month(create_time),user_id;
+------+---------+
| dt   | user_id |
+------+---------+
|    1 |   11211 |
|    1 |   75205 |
|    1 |   81384 |
|    1 |   50437 |
|    1 |   30321 |
|    1 |   49811 |
|    1 |   30352 |
|    1 |   30362 |
|    1 |   30363 |
|    1 |   30324 |
|    2 |   11211 |
|    2 |   75205 |
|    2 |   81384 |
|    2 |   30362 |
|    2 |   30363 |
|    2 |   30324 |
|    2 |   49262 |
|    2 |   12074 |
|    3 |   50437 |
|    3 |   30321 |
|    3 |   12074 |
|    3 |   81384 |
|    3 |   30362 |
|    3 |   27727 |
+------+---------+

第二步:查询每个月下过单的总用户数

select month(create_time) 月份,count(distinct user_id) 总用户数 
from order_info 
group by month(create_time);
+------+----------+
| 月份 | 总用户数 |
+------+----------+
|    1 |       10 |
|    2 |        8 |
|    3 |        6 |
+------+----------+

第三步:将每个月下过单的用户的查询结果作为临时表进行自连接,用月份和用户ID判断是否复购,计算次月的复购用户数

select t1.dt 自然月份,t2.dt 复购月份,count(distinct t2.user_id) 复购用户数 
from (select month(create_time) dt,user_id from order_info group by month(create_time),user_id) t1 
join (select month(create_time) dt,user_id from order_info group by month(create_time),user_id) t2 
on t1.user_id=t2.user_id and t1.dt < t2.dt 
group by t1.dt,t2.dt;
+----------+----------+------------+
| 自然月份 | 复购月份 | 复购用户数   |
+----------+----------+------------+
|        1 |        2 |          6 |
|        1 |        3 |          4 |
|        2 |        3 |          3 |
+----------+----------+------------+

第四步:复购率=复购用户数/总用户数

select 自然月份,复购月份,复购用户数,总用户数,round(复购用户数/总用户数,2) 复购率 
from 
(select t1.dt 自然月份,t2.dt 复购月份,count(distinct t2.user_id) 复购用户数 
from (select month(create_time) dt,user_id from order_info group by month(create_time),user_id) t1 
join (select month(create_time) dt,user_id from order_info group by month(create_time),user_id) t2 
on t1.user_id=t2.user_id and t1.dt < t2.dt 
group by t1.dt,t2.dt) a 
join 
(select month(create_time) 月份,count(distinct user_id) 总用户数 
from order_info 
group by month(create_time)) b 
on a.自然月份=b.月份;
+----------+----------+------------+----------+--------+
| 自然月份  | 复购月份 | 复购用户数  | 总用户数  | 复购率  |
+----------+----------+------------+----------+--------+
|        1 |        2 |          6 |       10 |   0.60 |
|        1 |        3 |          4 |       10 |   0.40 |
|        2 |        3 |          3 |        8 |   0.38 |
+----------+----------+------------+----------+--------+
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL计算复购率 的相关文章

  • MySQL 导入 125000 行 CSV 的最快方法?

    这是我第一次使用 MySQL 除了对现有数据库进行一些基本查询之外 所以我不擅长解决这个问题 我有一个包含 125 000 条记录的 CSV 我想将其加载到 MySQL 中 我安装了版本 8 和工作台 我使用导入向导加载 CSV 它开始导入
  • MySQL有两个不同的密码?

    我确信它们是不同事物的密码 但我不确定是什么 当在终端连接到 MySQL 时 我输入 usr LOCAL mysql BIN mysql h host u username p然后系统会提示我输入密码 密码是 但是当使用 PHP 连接到 M
  • 当数据表输入来自服务器的 JSON 数据时,更改 Google 图表栏颜色

    我一直在努力使用谷歌图表 API 我在 SO 上发现了这个出色的例子PHP MySQL Google Chart JSON 完整示例 https stackoverflow com questions 12994282 php mysql
  • Java 从 SQL 数组获取 ResultSet 失败

    我试图从数据库中检索电子邮件地址 但没有成功 我的代码如下 Main System out println PortfolioData getEmails 58 So Far Returning null 投资组合数据 public sta
  • 如果列有多个逗号分隔值,如何过滤 mysql 数据?

    我想问如果检查条件以查找具有多个逗号分隔值的列 如何过滤 mysql 数据 我给你举个例子 我有下表说 tbitems id item names item types item features 1 item 1 8 6 10 5 4 9
  • 在 MySQL 数据库中存储图像文件或 URL?哪个更好? [复制]

    这个问题在这里已经有答案了 可能的重复 在数据库中存储图像 是还是否 https stackoverflow com questions 3748 storing images in db yea or nay 数据库中的图像与文件系统中的
  • SQL 检查一组日期是否在指定的日期范围内

    我有一个表 其中保存架构中房间不可用的日期 ROOM ID DATE UNAVAILABLE 我需要一个 sql 查询来检查两个日期范围内是否有可用房间 类似于 Select All rooms that are constantly av
  • MySQL 全文搜索不适用于某些单词,例如“house”

    我已经在 3 个字段中的一小部分记录上设置了全文索引 也尝试了 3 个字段的组合 并得到了相同的结果 有些单词返回结果很好 但某些单词如 house 和 澳大利亚 不这样做 有趣的是 澳大利亚 和 家乡 这样做 这似乎是奇怪的行为 如果我添
  • MySQL 存储过程将值分配给 select 语句中的多个变量

    这是我的存储过程 我在为声明的变量赋值时遇到问题 当我执行它时 插入和更新命令工作正常 但声明变量的值保持为 0 但我在数据库中有一些价值 我怎样才能正确地做到这一点 BEGIN DECLARE PaidFee INT DEFAULT 0
  • 在 MacOSX10.6 上运行 python 服务器时 MySQLdb 错误

    运行我的服务器 python manage py runserver 产生以下错误 django core exceptions ImproperlyConfigured 加载 MySQLdb 模块时出错 没有名为 MySQLdb 的模块
  • 将记录分成两列

    我的数据库中有一个 学生 表 其中包含大约 5 000 条记录 我想将这些记录显示在two分区 如何在不执行查询两次的情况下做到这一点 仅使用单个查询 显示示例http www freeimagehosting net uploads f1
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • 如何使用 MySQL 的 LOAD DATA LOCAL INFILE 在导入 CSV 时将字符串日期更改为 MySQL 日期格式

    我正在使用 MySQL 的 LOAD DATA LOCAL INFILE SQL 语句将数据从 CSV 文件加载到现有数据库表中 下面是一个 SQL 语句示例 LOAD DATA LOCAL INFILE file csv INTO TAB
  • Hibernate 对集合的查询过滤器

    我想执行以下查询 from Item i where i categoryItems catalogId catId 然而 这会产生以下异常 非法尝试取消引用集合 所以我用谷歌搜索 找到了这个 Hibernate 论坛帖子https for
  • 截断 Mysql 表 Cron 作业?

    我在如何使用 cron 作业截断 Mysql 表时遇到了一些麻烦 无论我尝试什么 我似乎都无法让数据库清除表格 感谢您的帮助 mysql uderp example pexample hlocalhost Dexample e TRUNCA
  • Mysql 检索所有有限制的行

    我想检索特定用户的所有行 限制为 0 x 所以我只是想问是否有任何方法可以检索 mysql 中的所有行 而不调用返回 x 的 count id 的方法 而不重载现有函数 该函数在查询中根本没有限制 与我们的 string Relace 功能
  • MYSQL 区分大小写的 utf8 搜索(使用 hibernate)

    我的登录表具有 utf8 字符集和 utf8 排序规则 当我想要检查用户名并检索该特定用户名的其他信息时 hql 查询会为我提供小写和大写相同的结果 我应该如何处理适用于案例的 HQL 查询 我使用 Mysql 5 和 java hiber
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • MySQL PHP邮政编码比较具体距离

    我试图找出比较一个邮政编码 用户提供的 和一大堆其他邮政编码 现在大约有 200 个邮政编码 之间的距离的最有效方法 相对于加载时间 但它会随着时间的推移而增加 我不需要任何精确的东西 只是在球场上 我下载了整个美国的邮政编码 csv 文件
  • MySQL 查询计算上个月

    我想计算上个月的订单总额 我收到了从当前日期获取当月数据的查询 SELECT SUM goods total AS Total Amount FROM orders WHERE order placed date gt date sub c

随机推荐

  • 解决atibtmon.exe错误

    笔记本装好win7之后 折腾了一番 用驱动精灵更新了所有驱动 又装了林林种种的软件 继而用QQ管家优化系统 后来 发现系统在启动时 经常报错 atibtmon exe 如下 在网上搜了一番 有的说重装显卡驱动 有的说要重装visual c
  • XPath crash course note

    XPath language What is XPath To be supplied What is XPath for To be supplied Why XPath To be supplied basic concepts exa
  • exception in thread main java.lang.NoClassDefFoundError wrong name解决方法

    初学java时 在执行java文件时 可能会遇到java代码能编译通过 但执行文件时出现 exception in thread main java lang NoClassDefFoundError wrong name的错误 当不含包层
  • linux 清空文件内容的方式

    目录 一 通过重定向来清空文件内容 gt 通过shell重定向null到指定文件即可 gt 重定向 或 true 到指定文件 二 使用cat cp dd使用工具和 dev null设备来清空文件内容 gt 可以使用cat命令查看 dev n
  • Excel实现数据的线性回归

    文章目录 一 下载安装Excel 二 使用Excel做线性回归 三 验证回归方程的精度 四 参考资料 一 下载安装Excel 一般购买的电脑都已经安装好了Microsoft Office 就不需要进行下载安装这一过程 百度网盘链接 http
  • 记录一下Object.entries()的用法

    Object entries 方法返回一个给定对象自身可枚举属性的键值对数组 其排列与使用 for in 循环遍历该对象时返回的顺序一致 区别在于 for in 循环还会枚举原型链中的属性 语法 Object entries obj 参数
  • 赛车游戏——【极品飞车】(内含源码inscode在线运行)

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 前端炫酷代码分享 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架构咱们从0说 数据流通的精妙之道 文章目录 前言 认
  • MFC ActiveX 接口数据类型,伤不起!

    要不是因为我一直在维护一个曲线绘制控件 www st curve cn 我真的很不想再碰MFC的ActiveX了 其中怎一个乱字了得 回想起来 似乎还是vc6最好 后来我相继升级到了vc2003 2008 2010 每次升级都让我很受伤 注
  • 【机器学习】多分类及多标签分类算法(含源代码)

    目录 多分类及多标签分类算法 一 单标签二分类问题 1 1 单标签二分类算法原理 二 单标签多分类问题 2 1 ovo 2 1 1 手写代码 2 1 2 调用API 2 2 ovr 2 2 1 手写代码 2 2 2 调用API 2 3 Ov
  • 2022年十月份电赛OpenMV巡线方案(2)---主控代码详细分析

    前言 1 继上一篇 2022年十月份电赛OpenMV巡线方案详细代码分析 1 2 这个代码适用于所有主控 只需要更改一下串口接收部分的API 别问我某某MCU能不能跑的这种废话 3 本文使用的协议与正点原子的串口通讯协议一致 看不懂的建议学
  • 当前系统环境打成tar包

    当前系统环境打成tar包 原文地址 https www cnblogs com alexkn p 3879540 html 命令 tar numeric owner exclude proc exclude sys zcvf centos7
  • 【PlayWright教程(一)】安装和使用(python)

    当今常用的三个自动化测试 或者爬虫 库 库 Selenium Puppeteer Playwright JavaScript 支持 官方支持 官方支持 官方支持 Python 异步支持 无 第三方 而且 bug 不少 官方支持 Python
  • 使用bibmap修改bib文件中参考文献的期刊或会议名的字母大小写格式为titlecase

    使用bibmap方便的修改bib文件中参考文献的期刊或会议名的字母大小写格式为titlecase 1 引言 英文语句的字母大小写形式有多种格式 常用的格式是 全大写 upper case 即句子的所有字母都大写 常见于学位论文 报告等的封面
  • system.data.sqlite的源代码下载

    帮助文档 http system data sqlite org index html doc trunk www index wiki 历史版本https system data sqlite org index html doc tru
  • Kendo UI开发教程(14): Kendo MVVM 数据绑定(三) Click

    Click绑定可以把由ViewModel定义的方法不绑定到目标DOM的click事件 当点击目标DOM元素时触发ViewModel的对应方法 例如 使用Click绑定 1
  • Redis有序集合和定时任务解决订单15分钟关闭

    直接上代码 下单减去库存 public String updatePersonStock PageData pd throws Exception Map
  • IPSec协议

    内容提要 Motivation IP协议的安全缺陷 虚拟专用网 IPSec概述 协议流程 SPD SAD 数据封装 IPSec AH IPSec ESP 安全参数协商 ISAKMP IKE 一 Motivation 1 1IP协议的安全缺陷
  • Google Chrome 扩展程序

    Adblock Plus 扩展网址 https chrome google com webstore detail adblock plus free ad bloc cfhdojbkjhnklbpkdaibdccddilifddb 官网
  • uni-app底部导航栏tabBar监听变化以及变换样式

    一 简介 tabBar有三项 点击后两项变换tabBar的样式 二 案例演示 三 代码 1 首先 监听tabBar 点击切换 放在这三个页面 和onLoad同级 页面生命周期onTabItemTap 监听 TabBar 切换点击 onTab
  • SQL计算复购率

    需求背景 订单表中有每笔订单的下单时间 用户ID 订单金额等信息 需要统计每个月在接下来几个月用户复购情况 create table order info order id int primary key user id int amoun