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 相关文章推荐
MySQL大小写敏感的注意事项
May 24 MySQL
MySQL中出现乱码问题的终极解决宝典
May 26 MySQL
Mysql8.0递归查询的简单用法示例
Aug 04 MySQL
mysql中int(3)和int(10)的数值范围是否相同
Oct 16 MySQL
分享mysql的current_timestamp小坑及解决
Nov 27 MySQL
详解MySql中InnoDB存储引擎中的各种锁
Feb 12 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
Apr 18 MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 MySQL
MySQL 数据库 增删查改、克隆、外键 等操作
May 11 MySQL
MySQL提升大量数据查询效率的优化神器
Jul 07 MySQL
MySQL实现用逗号进行拼接、以逗号进行分割
Dec 24 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
Terran热键控制
2020/03/14 星际争霸
收集的DedeCMS一些使用经验
2007/03/17 PHP
PHP中CURL方法curl_setopt()函数的参数分享
2013/01/19 PHP
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
2013/02/06 PHP
浅析关于PHP位运算的简单权限设计
2013/06/30 PHP
PHP register_shutdown_function()函数的使用示例
2015/06/23 PHP
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
2011/05/24 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
2015/10/26 Javascript
jQuery Validate表单验证入门学习
2015/12/18 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
AngularJS 模型详细介绍及实例代码
2016/07/27 Javascript
原生JS实现的放大镜效果实例代码
2016/10/15 Javascript
JS制作适用于手机和电脑的通知信息效果
2016/10/28 Javascript
jquery插件锦集【推荐】
2016/12/16 Javascript
ES6中class类用法实例浅析
2017/04/06 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
jQuery ajax读取本地json文件的实例
2017/10/31 jQuery
JS实现字符串去重及数组去重的方法示例
2018/04/21 Javascript
详解Vue.js中.native修饰符
2018/04/24 Javascript
多个vue子路由文件自动化合并的方法
2019/09/03 Javascript
微信小程序实现点击按钮后修改颜色
2019/12/05 Javascript
实例讲解Python中函数的调用与定义
2016/03/14 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
2018/02/18 Python
解决sublime+python3无法输出中文的问题
2018/12/12 Python
英国百安居装饰建材网上超市:B&Q
2016/09/13 全球购物
ziaja齐叶雅官方海外旗舰店:来自波兰的天然护肤品牌
2017/01/02 全球购物
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
解除财产保全担保书
2014/05/20 职场文书
授权委托书
2014/07/31 职场文书
三关爱志愿服务活动方案
2014/08/17 职场文书
幼儿园开学家长寄语(2015秋季)
2015/05/27 职场文书
Vue Element UI自定义描述列表组件
2021/05/18 Vue.js
springboot项目以jar包运行的操作方法
2021/06/30 Java/Android
spring boot中nativeQuery的用法
2021/07/26 Java/Android
解决Mysql多行子查询的使用及空值问题
2022/01/22 MySQL
JavaScript实现一键复制内容剪贴板
2022/07/23 Javascript