MySQL查询根据按月分组的激活日期计算累积用户数
Posted
技术标签:
【中文标题】MySQL查询根据按月分组的激活日期计算累积用户数【英文标题】:MySQL query to count cumulative user number based on activation date groupped by month 【发布时间】:2020-10-20 20:14:22 【问题描述】:我有以下表格和数据:
CREATE TABLE tbl_users (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`activation_date` DATETIME
);
INSERT INTO tbl_users (id, activation_date) VALUES
(1, '2020-01-15' ),
(2, '2020-02-13' ),
(3, '2020-02-15' ),
(4, '2020-03-01' ),
(5, '2020-03-03' ),
(6, '2020-05-01' ),
(7, '2020-06-01' ),
(8, '2020-07-15' ),
(9, '2020-08-15' ),
(10, '2020-08-15' ),
(11, '2020-08-19' );
我正在寻找基于激活日期在每个月底计算用户汇总数的最佳方法。上面输出的测试数据应该如下所示:
month cumulative
1 1
2 3
3 5
4 5
5 6
6 7
7 8
8 11
9 11
10 11
我正在尝试:
SELECT MONTH(activation_date) as month, COUNT(*) as cumulative
FROM tbl_users
WHERE activation_date >= :start GROUP BY month
但我得到的是特定月份的值而不是累积值。 知道如何改进查询吗? 还是我需要稍后在 php 中处理它? 谢谢。
【问题讨论】:
您是在寻找“最佳方式”还是只是“一种方式”? 【参考方案1】:从 mysql 8.0 开始,您可以使用窗口函数来完成此任务:
SELECT DISTINCT
MONTH(activation_date) as month,
SUM(1) over (order by MONTH(activation_date) )as cumulative
FROM tbl_users
WHERE activation_date >= :start
;
SQLize.online
结果:
+-------+------------+
| month | cumulative |
+-------+------------+
| 1 | 1 |
| 2 | 3 |
| 3 | 5 |
| 5 | 6 |
| 6 | 7 |
| 7 | 8 |
| 8 | 11 |
+-------+------------+
【讨论】:
当没有用户被激活时,这几个月都无法生成一行,例如四月。【参考方案2】:如果您运行的是 MySQL 8.0,您可以使用递归查询来生成月份,然后将表带上 left join
,最后计算累积和:
with recursive cte as (
select
date_format(min(activation_date), '%Y-%m-01') dt,
date_format(max(activation_date), '%Y-%m-01') max_dt
from tbl_users
union all
select dt + interval 1 month, max_dt
from cte
where dt < max_dt
)
select c.dt, sum(count(u.id)) over(order by dt) cumulative
from cte c
left join tbl_users u
on u.activation_date >= c.dt
and u.activation_date < c.dt + interval 1 month
group by c.dt
order by c.dt
请注意,这会直接从表格中的可用日期生成日期范围的下限和上限,这似乎比使用固定范围更明智。
Demo on DB Fiddle:
dt |累积 :--------- | ---------: 2020-01-01 | 1 2020-02-01 | 3 2020-03-01 | 5 2020-04-01 | 5 2020-05-01 | 6 2020-06-01 | 7 2020-07-01 | 8 2020-08-01 | 11【讨论】:
只是一个务实的问题:对于大型表(几 k 行)并且通常是查询,是否建议使查询复杂化,或者仅针对月份值并在将数据检索到PHP数组?这种递归操作对数据库的影响会很大吗?谢谢!以上是关于MySQL查询根据按月分组的激活日期计算累积用户数的主要内容,如果未能解决你的问题,请参考以下文章