【MySQL】MySQL统计每个月初注册的总人数

需求

假设有下列表(user_reg),第一列为id,第二列为注册时间(dt),该表记录了每个id的注册时间
在这里插入图片描述

现在要统计每个月初(每个月1日)注册的总用户数,时间顺序排序,结果如下
在这里插入图片描述

解决方案

  1. 统计数量必然要使用分组,因此首先要考虑的问题是如何将本月2日到下月1日之间的数据分到一组。这里使用case when进行判断,当日期大于本月第一天的时候返回下个月第一天,否则不变,即
    在这里插入图片描述
SELECT
	dt,
	CASE WHEN dt > DATE_SUB( dt, INTERVAL DAYOFMONTH( dt )- 1 DAY ) THEN DATE_ADD( LAST_DAY( dt ), INTERVAL 1 DAY ) ELSE dt END AS dt1 
FROM
	user_reg;

这里计算本月第一天时使用当前日期减去当前日期在本月的天数(DAYOFMONTH)-1,计算下月第一天时用本月最后一天(LAST_DAY)加1天,这样dt1相同的时候就是一组的数据。

  1. 然后再使用group by对dt1进行分组并统计数量,得到如下结果
    在这里插入图片描述
SELECT
	CASE WHEN dt > DATE_SUB( dt, INTERVAL DAYOFMONTH( dt )- 1 DAY ) THEN DATE_ADD( LAST_DAY( dt ), INTERVAL 1 DAY ) ELSE dt END AS dt1,
	count(1) as cnt
FROM
	user_reg
GROUP BY
	dt1;
  1. 最后就是考虑如何把cnt的值进行统计,即求从最开始到当前行的和,这里使用开窗聚合函数SUM
SELECT
	dt1,
	sum( cnt ) over ( ORDER BY dt1 rows BETWEEN unbounded preceding AND current ROW ) AS cnt 
FROM
	(
	SELECT
		CASE WHEN dt > DATE_SUB( dt, INTERVAL DAYOFMONTH( dt )- 1 DAY ) THEN DATE_ADD( LAST_DAY( dt ), INTERVAL 1 DAY ) ELSE dt END AS dt1,
		COUNT( 1 ) AS cnt 
	FROM
		user_reg 
	GROUP BY
		dt1 
	) t;

通过dt1进行升序排序,对cnt进行求和,求和范围是开始到当前行。

猜你喜欢

转载自blog.csdn.net/weixin_42147967/article/details/127406236