mysql统计用户每天请求次数,5分钟内同一个用户请求算一次

来源:互联网 发布:远程网络打印机 编辑:程序博客网 时间:2024/05/19 11:50

需求为:统计所有用户每天的请求次数,但是在用户发起第一次请求开始,5分钟内的请求都只算一次;


代码思路:

获取每个用户每天的总数 - 用户每天在5分钟重复的次数;

1、查出用户第一次请求时间,计算从这次时间开始的5分钟内,有多少次请求;

2、获取5分钟后,第一次最小请求时间,计算从这次时间开始的5分钟内,有多少次请求,并累加;

3、循环,直到没有最小时间;

4、用总次数 - 重复的次数 = 所有不重复的请求次数


代码架构:

存储过程:计算总数和结果;

函数:返回累加用户在所有5分钟重复的次数;

存储过程:统计用户每次在5分钟重复的次数;

存储过程:获取用户下一个5分钟的最小时间;


详细代码:

计算总数和结果:

-- 
-- 按天统计
--  
--
DROP PROCEDURE IF EXISTS  p_getCountByDay  ;
CREATE PROCEDURE p_getCountByDay()


BEGIN

declare out_count_day int;  -- 天统计数
declare _min_date datetime; -- 最小时间


###获取最大的时间和重复的次数
SELECT date_format(d.create_date, '%Y%m%d') , (COUNT(1) - fn_get_count_day(date_format(d.create_date, '%Y%m%d'))) 
FROM table_1 d
GROUP BY date_format(d.create_date, '%Y%m%d') 
;


END


-----------------------------------------------------------------

返回累加用户在所有5分钟重复的次数:

-- 
-- 获取重复认证的用户重复的次数
-- 函数过程名为:fn_get_count_day
-- 参数为:param_date 传入时间
-- 
--
DROP FUNCTION IF EXISTS fn_get_count_day  ;
CREATE FUNCTION fn_get_count_day(param_date varchar(50)) RETURNS int  
    BEGIN  
    
declare _user_id int; -- 用户名
declare _min_date datetime; -- 最小时间
declare done int;
declare repet_count int;
declare max_date datetime;
declare out_repet_count INT;


-- 定义游标
-- 获取当天时间的有重复扫描的用户
DECLARE rs_cursor CURSOR FOR 
SELECT user_id FROM(
SELECT d.user_id,COUNT(1) c FROM table_1 d
WHERE date_format(d.create_date, '%Y%m%d') = param_date
GROUP BY d.user_id
) t 
WHERE c > 1
;


DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
SET out_repet_count = 0;
SET repet_count = 0;
SET max_date = NULL;


open rs_cursor; 
cursor_loop:loop
FETCH rs_cursor into _user_id; -- 取数据


if done=1 then
leave cursor_loop;
end if;


-- 获取当前用户最小时间
SELECT MIN(r.create_date) into _min_date 
FROM table_1 r 
WHERE r.user_id = _user_id
AND date_format(r.create_date, '%Y%m%d') = param_date
;


# 获取当前用户第一次5分钟内连接的次数
# 统计用户重复次数
# 获取当前用户5分钟后的最小时间
CALL p_getRepeatCount(_min_date,_user_id,param_date,repet_count);
SET out_repet_count = repet_count + out_repet_count ;
CALL p_getNextMinDate(_min_date,_user_id,param_date,max_date);
SET _min_date = max_date;



####循环统计用户重复数据
WHILE max_date IS NOT NULL DO 
CALL p_getRepeatCount(_min_date,_user_id,param_date,repet_count);
SET out_repet_count = repet_count + out_repet_count ;
CALL p_getNextMinDate(_min_date,_user_id,param_date,max_date);
SET _min_date = max_date;
END WHILE;


end loop cursor_loop;
close rs_cursor;


    RETURN out_repet_count;  

END     


---------------------------------------------------------------------------

统计用户每次在5分钟重复的次数;



-- 
-- 计算5分钟之内的次数
-- 传入参数:in_user_id  : 用户ID ;
-- 传入参数:in_min_date : 当前最小时间
-- 返回值:repet_count:重复次数
--
DROP PROCEDURE IF EXISTS  p_getRepeatCount  ; 
CREATE PROCEDURE p_getRepeatCount(IN in_min_date datetime,
IN in_user_id INT,
IN param_date VARCHAR(50),
out out_re_count INT)


BEGIN

###获取最大的时间和重复的次数
SELECT COUNT(1) into out_re_count
FROM table_1 d
WHERE d.user_id = in_user_id
AND d.create_date <= date_add(in_min_date,interval 5 minute)
AND d.create_date > in_min_date
AND date_format(d.create_date, '%Y%m%d') = param_date
;


END


---------------------------------------------------------------------------

获取用户下一个5分钟的最小时间:


-- 
-- 获取下一个最小的时间
-- 存储过程名为:p_getNextMinDate
-- 传入参数:in_user_id  : 用户ID ;
-- 传入参数:in_min_date : 当前最小时间
-- 返回值:out_max_date:下一个最小的时间
--
DROP PROCEDURE IF EXISTS p_getNextMinDate  ;
CREATE PROCEDURE p_getNextMinDate(IN in_min_date datetime,
IN in_user_id INT,
IN param_date VARCHAR(50),
out out_max_date datetime)


BEGIN

###获取最大的时间和重复的次数
SELECT MIN(create_date) into out_max_date 
FROM table_1 d
WHERE d.user_id = in_user_id
AND d.create_date > date_add(in_min_date,interval 5 minute)
AND date_format(d.create_date, '%Y%m%d') = param_date
;


END


-------------------------------------------------------

第一篇博客,暂时不会排版,后期优化;


原创粉丝点击