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');
创建存储过程:
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;