mysql 动态统计某时间内登陆次数

最近公司里做遇到了一点麻烦的事情,需要根据时间动态的查询每日每月的二维码扫描量以及优惠卷使用量。我想着,这不跟动态统计某时间内登陆次数之类的业务场景这种需求大致上是一样的吗,接下来我就用如标题所示的业务场景解决这个问题。

创建用户登录记录表,假定用户每登录一次向此表存入一条数据


CREATE TABLE `user_login_record` (
	`id`  VARCHAR(16) NOT NULL COMMENT '主键',
    `user_id` VARCHAR(16) NOT NULL COMMENT '用户id',
    `login_time` datetime NOT NULL COMMENT '登陆时间',
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;


准备数据

INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1111','00001','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1112','00001','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1113','00001','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1114','00001','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1115','00001','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1116','00001','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1117','00001','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1118','00001','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1119','00001','2019-06-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1120','00001','2019-06-04 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1122','00001','2019-06-04 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1123','00001','2019-05-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1124','00001','2019-05-12 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1125','00001','2019-05-10 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1126','00001','2019-05-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1127','00001','2019-05-19 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1128','00001','2019-05-20 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1129','00001','2019-06-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1130','00001','2019-06-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1131','00001','2019-06-08 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1132','00001','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1133','00002','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1134','00002','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1135','00002','2019-06-13 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1136','00002','2019-06-12 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1137','00002','2019-06-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1138','00002','2019-06-08 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1139','00003','2019-06-10 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1140','00003','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1141','00003','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1142','00003','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1143','00003','2019-06-20 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1144','00003','2019-06-14 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1145','00003','2019-06-10 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1146','00003','2019-06-10 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1147','00004','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1148','00004','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1149','00004','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1150','00004','2019-06-11 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1151','00004','2019-06-18 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1152','00004','2019-06-13 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1153','00004','2019-06-15 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1154','00004','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1155','00004','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1156','00004','2019-06-30 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1157','00004','2019-06-09 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1158','00004','2019-06-20 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1159','00004','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1160','00005','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1161','00005','2019-07-03 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1162','00005','2019-07-01 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1163','00005','2019-07-02 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1164','00005','2019-06-30 15:51:58');INSERT INTO `popuconsole`.`user_login_record`(`id`,`user_id`,`login_time`) VALUES ('1165','00005','2019-06-10 15:51:58');

问题:那怎么通过一个sql 查询出不同用户在不同时间内的登陆次数呢?

如果 group by 用户id,则时间作为了动态的列;如果group by 登陆时间,则用户id作为了动态的列,那么 怎么查询如下图所示的语句呢?

mysql 动态统计某时间内登陆次数_第1张图片

如果要我直接写sql语句的话 我会这么写

SELECT
	user_id AS userId,
	SUM( IF ( DATE_FORMAT( login_time, '%Y%m' ) = '201905', 1, 0 ) ) AS '201905',
	SUM( IF ( DATE_FORMAT( login_time, '%Y%m' ) = '201906', 1, 0 ) ) AS '201906',
	SUM( IF ( DATE_FORMAT( login_time, '%Y%m' ) = '201907', 1, 0 ) ) AS '201907' 
FROM
	user_login_record 
GROUP BY
	user_id

从上面的sql 上来看 这是一个静态的sql,那么 如何的确定有多少个月,每个月如何的显示呢?即,sum()是怎么得来的?

现在需要介绍两个mysql 函数

1、group_concat() :将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

2、ONCAT(str1,str2,…) :返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。


SELECT
	GROUP_CONCAT(
	DISTINCT CONCAT( 'SUM(IF(DATE_FORMAT(login_time,''%Y%m'') = ''', DATE_FORMAT( c.login_time, '%Y%m' ), ''',1, 0)) AS ''', DATE_FORMAT( c.login_time, '%Y%m' ), '''' ) 
	) 
FROM
	user_login_record c 
WHERE
	c.login_time

通过以上的sql可以得出 一系列sum()函数的字符串 。但是是没法通过一个sql查询出来的,以上的步骤 只等通过 查询出结果字符串 然后把结果字符串粘贴过去生成查询结果。

自然而然的 想到了存储 过程下面 我创建了一个不带条件的存储过程

CREATE DEFINER=`root`@`%` PROCEDURE `UserLoginTimesSatistics`()
BEGIN
SET @sql = NULL;

SELECT
	GROUP_CONCAT(
	DISTINCT CONCAT( 'SUM(IF(DATE_FORMAT(login_time,''%Y%m'') = ''', DATE_FORMAT( c.login_time, '%Y%m' ), ''',1, 0)) AS ''', DATE_FORMAT( c.login_time, '%Y%m' ), '''' ) 
	) 
FROM
	user_login_record c 
WHERE
	c.login_time INTO  @sql ;


SELECT  CONCAT( 'SELECT  user_id as userId ,  ', @sql, ' from user_login_record  GROUP BY user_id' ) INTO @sql;


PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 

END

保存成功之后 直接通过

call UserLoginTimesSatistics()

就可以得到上图所示结果 是不是很酷

自然而然的,动态的统计某时间内登陆的次数只需要将上述的存储过程改进一下就行了,我的改进如下

CREATE DEFINER=`root`@`%` PROCEDURE `UserLoginTimesSatistics`( IN beginTime VARCHAR(50),IN endTime VARCHAR(50) )
BEGIN
SET @sql = NULL;

if ( beginTime = '' || beginTime is NULL  || endTime ='' || endTime is NULL) THEN
SELECT
	GROUP_CONCAT(
	DISTINCT CONCAT( 'SUM(IF(DATE_FORMAT(login_time,''%Y%m'') = ''', DATE_FORMAT( c.login_time, '%Y%m' ), ''',1, 0)) AS ''', DATE_FORMAT( c.login_time, '%Y%m' ), '''' ) 
	) 
FROM
	user_login_record c  INTO  @sql ;
ELSE

SELECT
	GROUP_CONCAT(
	DISTINCT CONCAT( 'SUM(IF(DATE_FORMAT(login_time,''%Y%m%d'') = ''', DATE_FORMAT( c.login_time, '%Y%m%d' ), ''',1, 0)) AS ''', DATE_FORMAT( c.login_time, '%Y%m%d' ), '''' ) 
	) 
FROM
	user_login_record c 
WHERE  DATEDIFF(beginTime,c.login_time)<=0 and DATEDIFF(c.login_time,endTime)<=0  INTO  @sql ;

END IF ;


SELECT  CONCAT( 'SELECT  user_id as userId ,  ', @sql, ' from user_login_record  GROUP BY user_id' ) INTO @sql;


PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 

END

查询测试

call UserLoginTimesSatistics('2019/07/01','2019/07/03');

结果如下
mysql 动态统计某时间内登陆次数_第2张图片

你可能感兴趣的:(mysql 动态统计某时间内登陆次数)