MySQL去除重叠时间求时间差和的实现


Posted in MySQL onAugust 23, 2021

         我个人并不推荐在实际开发中使用存储过程,充满了各种的不方便,之所以写这东西,全在于学习,如果有高手看到我的内容有问题,可以随时指出或向我开炮。 

需求:

        在生产中常常出现计算两个时间差的业务,比如总宕机时间、总开通会员时间等等。。。但是这些时间往往不是连贯的,断断续续,甚至可能会出现重叠的情况。无法直接求出时间差。

例如:

MySQL去除重叠时间求时间差和的实现

MySQL去除重叠时间求时间差和的实现

 开车:

        一开始,我想的是用单条SQL实现,例如:↓

SELECT TIMESTAMPDIFF(MINUTE, '2021-08-19 14:30:00', '2021-08-19 15:00:00') FROM DUAL;

 我发现,数据库数据千千万,不可能这样,也不可能用UNION这种东西去拼接,数据很多,就一定会有循环,所以,在不使用Java语言的情况下,我选择尝试用存储过程来解决以下这个问题。

思路:

         首先,一次进入循环的数据不会进行计算,防止后边的数据和它有重叠,

        从第二条数据开始,就要判断开始时间是否和上一个数据重叠,如果重叠,则校验结束时间是否也重叠,如果重叠我就啥也不干,不重叠,则把这个值赋给上一次的数据的结束时间。

        如果开始时间不再范围内,那么需要判断开始时间是在上一次时间的之前还是之后

        如果这个范围之前,把这个值赋给上一次的数据的开始时间。

        在这个范围之后,计算并赋值

        最后一次循环也要计算并赋值

实现:        

首先创建表,模拟数据

CREATE TABLE test01 (
  id int(32) unsigned NOT NULL AUTO_INCREMENT,
  start_time datetime NOT NULL,
  end_time datetime NOT NULL,
  PRIMARY KEY (`id`)
) 
 
INSERT INTO test01(id, start_time, end_time) VALUES (1, '2021-08-18 16:27:51', '2021-08-18 17:27:59');
INSERT INTO test01(id, start_time, end_time) VALUES (2, '2021-08-18 17:20:26', '2021-08-18 20:10:37');
INSERT INTO test01(id, start_time, end_time) VALUES (3, '2021-08-18 22:05:57', '2021-08-18 23:55:20');

 MySQL去除重叠时间求时间差和的实现

 创建存储过程:

CREATE PROCEDURE sumTime()
BEGIN
    -- 定义变量 
 
    -- 是否首次
    DECLARE is_old int(1) DEFAULT 0;
 
    -- 上一次数据
	DECLARE old_start_time datetime;
	DECLARE old_end_time datetime;
 
	-- 本次数据
	DECLARE start_time datetime;
	DECLARE end_time datetime;
 
	-- 返回结果
	DECLARE num int(32) DEFAULT 0;
 
	-- 循环结束开关
	DECLARE done int DEFAULT 0;
 
	-- 创建游标(查询数据库数据)
	DECLARE list CURSOR FOR SELECT a.start_time, a.end_time FROM test01 a;
 
    -- 定义最后一次循环时设置 循环结束开关 为 1
	DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
 
	-- 开启游标
	OPEN list;
 
		-- 开启循环
		posLoop:LOOP
			-- 取值 将当前循环的值取出 赋值给当前数据变量
			FETCH list INTO start_time,end_time;
			-- 判断是否首次
			if (is_old = 0) THEN 
 
				SET is_old = 1;
				SET old_start_time = start_time;
				SET old_end_time = end_time;
 
			-- 否则
			ELSE
				-- 校验是否在区间内
				 if (start_time >= old_start_time AND start_time <= old_end_time) THEN
 
					-- 校验结束时间是否不在在区间内
				   if (end_time < old_start_time OR end_time > old_end_time) THEN
						SET old_end_time = end_time;
				   END IF;
 
				 -- 否则
				 ELSE
 
				   if (start_time < old_start_time )  THEN
 
						SET old_start_time = start_time;
 
					 ELSE
 
						SET num = num + TIMESTAMPDIFF(MINUTE, old_start_time, old_end_time);
						SET old_start_time = start_time;
						SET old_end_time = end_time;
					 END IF;
				 END IF;
			END IF;
			-- 校验是否最后一次循环
			IF done=1 THEN 
			    SET num = num + TIMESTAMPDIFF(MINUTE, old_start_time, old_end_time);
			    LEAVE posLoop;
			END IF;
		-- 结束循环	
		END LOOP posLoop;
	-- 关闭游标 
	CLOSE list;
	SELECT num;
END;
-- 调用存储过程
call sumTime();

 MySQL去除重叠时间求时间差和的实现

-- 删除存储过程
drop procedure if exists sumTime;

到此这篇关于MySQL去除重叠时间求时间差和的实现的文章就介绍到这了,更多相关MySQL 求时间差和内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
数据库连接池
Apr 06 MySQL
MySQL表的增删改查基础教程
Apr 07 MySQL
如何使用Maxwell实时同步mysql数据
Apr 08 MySQL
教你用eclipse连接mysql数据库
Apr 22 MySQL
如何设计高效合理的MySQL查询语句
May 26 MySQL
详解MySQL多版本并发控制机制(MVCC)源码
Jun 23 MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 MySQL
MySQL数据库完全卸载的方法
Mar 03 MySQL
Mysql外键约束的创建与删除的使用
Mar 03 MySQL
关于k8s环境部署mysql主从的问题
Mar 13 MySQL
关于mysql中string和number的转换问题
Jun 14 MySQL
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
Aug 23 #MySQL
MySQL的全局锁和表级锁的具体使用
Aug 23 #MySQL
MySQL令人大跌眼镜的隐式转换
Aug 23 #MySQL
SQL IDENTITY_INSERT作用案例详解
Aug 23 #MySQL
MySQL非空约束(not null)案例讲解
Aug 23 #MySQL
MySQL外键约束(FOREIGN KEY)案例讲解
Aug 23 #MySQL
MySQL 1130异常,无法远程登录解决方案详解
Aug 23 #MySQL
You might like
php 删除cookie和浏览器重定向
2009/03/16 PHP
PHP之短标签开启设置
2013/06/17 PHP
PHP获取中英混合字符串长度的方法
2014/06/07 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
PHP那些琐碎的知识点(整理)
2017/05/20 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
php 广告点击统计代码(php+mysql)
2018/02/21 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
超清晰的document对象详解
2007/02/27 Javascript
Javascript学习笔记4 Eval函数
2010/01/11 Javascript
6个DIV 135或246间隔一秒轮番显示效果
2010/07/24 Javascript
js报错 Object doesn't support this property or method的原因分析
2011/03/31 Javascript
基于Jquery的开发个代阴影的对话框效果代码
2011/07/28 Javascript
将文本输入框内容加入表中的js代码
2013/08/18 Javascript
鼠标滚轴控制文本框值的JS代码
2013/11/19 Javascript
通用javascript代码判断版本号是否在版本范围之间
2015/11/29 Javascript
Node.js的特点详解
2017/02/03 Javascript
layui文件上传实现代码
2017/05/20 Javascript
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
JavaScript数据结构之双向链表定义与使用方法示例
2017/10/27 Javascript
[04:29]2016国际邀请赛中国区预选赛Ehome战队教练采访
2016/06/27 DOTA
[36:41]完美世界DOTA2联赛循环赛FTD vs Magma第一场 10月30日
2020/10/31 DOTA
[22:07]DOTA2-DPC中国联赛 正赛 iG vs Magma 选手采访
2021/03/11 DOTA
教大家使用Python SqlAlchemy
2016/02/12 Python
Python简单计算数组元素平均值的方法示例
2017/12/26 Python
美国高街时尚品牌:OASAP
2016/07/24 全球购物
西班牙国家航空官方网站:Iberia
2017/11/16 全球购物
Hotter Shoes美国官网:英国最受欢迎的舒适鞋
2018/08/02 全球购物
HSRP的含义以及如何工作
2014/09/10 面试题
Python里面如何拷贝一个对象
2014/02/17 面试题
实习心得体会
2014/01/02 职场文书
幼儿园大班新学期寄语
2014/01/18 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python
MySQL为id选择合适的数据类型
2021/06/07 MySQL
html5实现点击弹出图片功能
2021/07/16 HTML / CSS