佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > MySQL去除重疊時間求時間差和的實現(xiàn)

MySQL去除重疊時間求時間差和的實現(xiàn)

熱門標簽:百度競價排名 Linux服務(wù)器 AI電銷 鐵路電話系統(tǒng) 呼叫中心市場需求 地方門戶網(wǎng)站 服務(wù)外包 網(wǎng)站排名優(yōu)化

         我個人并不推薦在實際開發(fā)中使用存儲過程,充滿了各種的不方便,之所以寫這東西,全在于學(xué)習(xí),如果有高手看到我的內(nèi)容有問題,可以隨時指出或向我開炮。 

需求:

        在生產(chǎn)中常常出現(xiàn)計算兩個時間差的業(yè)務(wù),比如總宕機時間、總開通會員時間等等。。。但是這些時間往往不是連貫的,斷斷續(xù)續(xù),甚至可能會出現(xiàn)重疊的情況。無法直接求出時間差。

例如:

 開車:

        一開始,我想的是用單條SQL實現(xiàn),例如:↓

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

 我發(fā)現(xiàn),數(shù)據(jù)庫數(shù)據(jù)千千萬,不可能這樣,也不可能用UNION這種東西去拼接,數(shù)據(jù)很多,就一定會有循環(huán),所以,在不使用Java語言的情況下,我選擇嘗試用存儲過程來解決以下這個問題。

思路:

         首先,一次進入循環(huán)的數(shù)據(jù)不會進行計算,防止后邊的數(shù)據(jù)和它有重疊,

        從第二條數(shù)據(jù)開始,就要判斷開始時間是否和上一個數(shù)據(jù)重疊,如果重疊,則校驗結(jié)束時間是否也重疊,如果重疊我就啥也不干,不重疊,則把這個值賦給上一次的數(shù)據(jù)的結(jié)束時間。

        如果開始時間不再范圍內(nèi),那么需要判斷開始時間是在上一次時間的之前還是之后

        如果這個范圍之前,把這個值賦給上一次的數(shù)據(jù)的開始時間。

        在這個范圍之后,計算并賦值

        最后一次循環(huán)也要計算并賦值

實現(xiàn):        

首先創(chuàng)建表,模擬數(shù)據(jù)

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');

 

 創(chuàng)建存儲過程:

CREATE PROCEDURE sumTime()
BEGIN
    -- 定義變量 
 
    -- 是否首次
    DECLARE is_old int(1) DEFAULT 0;
 
    -- 上一次數(shù)據(jù)
	DECLARE old_start_time datetime;
	DECLARE old_end_time datetime;
 
	-- 本次數(shù)據(jù)
	DECLARE start_time datetime;
	DECLARE end_time datetime;
 
	-- 返回結(jié)果
	DECLARE num int(32) DEFAULT 0;
 
	-- 循環(huán)結(jié)束開關(guān)
	DECLARE done int DEFAULT 0;
 
	-- 創(chuàng)建游標(查詢數(shù)據(jù)庫數(shù)據(jù))
	DECLARE list CURSOR FOR SELECT a.start_time, a.end_time FROM test01 a;
 
    -- 定義最后一次循環(huán)時設(shè)置 循環(huán)結(jié)束開關(guān) 為 1
	DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
 
	-- 開啟游標
	OPEN list;
 
		-- 開啟循環(huán)
		posLoop:LOOP
			-- 取值 將當前循環(huán)的值取出 賦值給當前數(shù)據(jù)變量
			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
				-- 校驗是否在區(qū)間內(nèi)
				 if (start_time >= old_start_time AND start_time = old_end_time) THEN
 
					-- 校驗結(jié)束時間是否不在在區(qū)間內(nèi)
				   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;
			-- 校驗是否最后一次循環(huán)
			IF done=1 THEN 
			    SET num = num + TIMESTAMPDIFF(MINUTE, old_start_time, old_end_time);
			    LEAVE posLoop;
			END IF;
		-- 結(jié)束循環(huán)	
		END LOOP posLoop;
	-- 關(guān)閉游標 
	CLOSE list;
	SELECT num;
END;
-- 調(diào)用存儲過程
call sumTime();

 

-- 刪除存儲過程
drop procedure if exists sumTime;

到此這篇關(guān)于MySQL去除重疊時間求時間差和的實現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL 求時間差和內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • MySQL 到底是如何做到多版本并發(fā)的?
  • mysql過濾復(fù)制思路詳解
  • MySQL 外鍵(FOREIGN KEY)用法案例詳解
  • MySQL如何利用存儲過程快速生成100萬條數(shù)據(jù)詳解
  • Python接口自動化淺析pymysql數(shù)據(jù)庫操作流程
  • MySQL事務(wù)控制流與ACID特性
  • Mysql使用存儲過程快速添加百萬數(shù)據(jù)的示例代碼
  • Mysql數(shù)據(jù)庫中datetime、bigint、timestamp來表示時間選擇,誰來存儲時間效率最高
  • MySQL的全局鎖和表級鎖的具體使用
  • 基于Redo Log和Undo Log的MySQL崩潰恢復(fù)解析

標簽:銅川 黃山 湘潭 蘭州 崇左 衡水 仙桃 湖南

巨人網(wǎng)絡(luò)通訊聲明:本文標題《MySQL去除重疊時間求時間差和的實現(xiàn)》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    靖宇县| 耒阳市| 宽甸| 壶关县| 阿拉善左旗| 韶关市| 南平市| 台北县| 江都市| 苗栗县| 太保市| 邵阳县| 雅江县| 兴安盟| 德庆县| 崇信县| 和平县| 静海县| 扎赉特旗| 北流市| 金沙县| 正安县| 鹤庆县| 江川县| 会东县| 华容县| 洪雅县| 东乡县| 阿拉善左旗| 城固县| 陕西省| 乐平市| 高平市| 仲巴县| 日照市| 忻城县| 通榆县| 汝州市| 盐边县| 工布江达县| 特克斯县|