首页
/
每日頭條
/
職場
/
mysql中求大于某個日期的數據
mysql中求大于某個日期的數據
更新时间:2026-05-14 00:55:01
前言

最近小編在項目中遇到需要查詢某個工單還有多少剩餘處理時間的需求,并且要按照工作時的計算方式,對剩餘處理時間按升序排列,如果是對查詢出來的工單進行剩餘時間計算,那麼在程序中就能夠完成,但偏偏要求需要進行排序,這可就難了,因為數據表内記錄超過百萬,放在程序中處理肯定會溢出,最終還是選擇加個mysql函數,讓數據庫幫忙處理,但找遍各大論壇也沒有找到在mysql中計算工作時的方法,無奈隻能自己來寫個,在這裡分享給大家!

不說廢話,直接上代碼!

說明

這裡要說明一下函數中使用的 frame_workingday 這個表,這是一張日曆表,記錄了哪天是工作日,跟百度搜索的萬年曆一樣的

mysql中求大于某個日期的數據(工作時工作日函數)1

mysql中求大于某個日期的數據(工作時工作日函數)2

表結構

完整代碼

drop function if exists getworkminute; create function getworkminute(starttime datetime, endtime datetime) returns integer begin -- 聲明變量 -- -- 最終結果 declare interval_minute integer default 0; -- 開始時間是否工作日 declare startiswork integer default 0; -- 結束時間是否工作日 declare endiswork integer default 0; -- 開始時間與結束時間之間的工作日天數,包含自身 declare workdaynum integer default 0; -- 定義上午、下午 上下班時間 -- set @monworkstart = '08:00:00'; set @monworkend = '12:00:00'; set @noonworkstart = '14:00:00'; set @noonworkend = '18:00:00'; set @startdate = date_format(starttime,'%Y-%m-%d'); set @enddate = date_format(endtime,'%Y-%m-%d'); set @timestart = date_format(starttime, '%H:%i:%s'); set @timeend = date_format(endtime, '%H:%i:%s'); -- 查詢 select count((@startdate = wdate and isworkingday = 1) or null) , count((@enddate = wdate and isworkingday = 1) or null) , count(isworkingday = 1 or null) into startiswork,endiswork,workdaynum from frame_workingday where wdate between @startdate and @enddate; -- 如果開始和結束時間是同一天,且是工作日 if @startdate = @enddate and startiswork = 1 and endiswork = 1 then set workdaynum = 0; -- 開始時間小于上午上班時間 if @timestart < @monworkstart then -- 結束時間處于上午工作時間,計算 上午上班時間與結束時間間隔 if @timeend > @monworkstart and @timeend < @monworkend then set interval_minute = interval_minute timestampdiff(minute, concat(@startdate,' ',@monworkstart), concat(@startdate,' ', @timeend)); -- 結束時間處于午休時間,計算 半天 elseif @timeend >= @monworkend and @timeend <= @noonworkstart then set interval_minute = interval_minute 240; -- 結束時間處于下午工作時間,計算 半天 下午上班時間與結束時間間隔 elseif @timeend >= @noonworkstart and @timeend <= @noonworkend then set interval_minute = interval_minute 240 timestampdiff(minute, concat(@startdate,' ',@noonworkstart), concat(@startdate,' ', @timeend)); -- 結束時間大于下午下班時間,計算 一天 elseif @timeend >= @noonworkend then set interval_minute = interval_minute 480; end if; -- 開始時間小于上午下班時間 elseif @timestart < @monworkend then -- 結束時間小于上午下班時間,計算 開始時間與結束時間間隔 if @timeend < @monworkend then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @timeend)); -- 結束時間是午休時間,計算 開始時間與上午下班時間間隔 elseif @timeend >= @monworkend and @timeend <= @noonworkstart then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @monworkend)); -- 結束時間在下午工作時間,計算 開始時間與上午下班時間間隔 下午上班時間與結束時間間隔 elseif @timeend >= @noonworkstart and @timeend <= @noonworkend then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @monworkend)) timestampdiff(minute, concat(@startdate,' ',@noonworkstart), concat(@startdate,' ', @timeend)); -- 結束時間大于下午下班時間 計算 開始時間與上午下班時間間隔 半天 elseif @timeend>= @noonworkend then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @monworkend)) 240; end if; -- 開始時間小于下午上班時間,即處于午休時間 elseif @timestart < @noonworkstart then -- 結束時間小于下午上班時間,計算 0 if @timeend < @noonworkstart then set interval_minute = interval_minute 0; -- 結束時間在下午工作時間,計算 下午上班時間與結束時間間隔 elseif @timeend >= @noonworkstart and @timeend <= @noonworkend then set interval_minute = interval_minute timestampdiff(minute, concat(@startdate,' ',@noonworkstart), concat(@startdate,' ', @timeend)); -- 結束時間大于下午下班時間 計算 半天 elseif @timeend>= @noonworkend then set interval_minute = interval_minute 240; end if; -- 開始時間小于下午下班時間 elseif @timestart < @noonworkend then -- 結束時間小于下午下班時間,計算 開始時間與結束時間間隔 if @timeend < @noonworkend then set interval_minute = interval_minute timestampdiff(minute, concat(@startdate,' ',@timestart), concat(@startdate,' ', @timeend)); -- 結束時間大于下午下班時間,計算 開始時間與下午下班時間間隔 elseif @timeend >= @noonworkend then set interval_minute = interval_minute timestampdiff(minute, concat(@startdate,' ',@timestart), concat(@startdate,' ', @noonworkend)); end if; end if; else -- 不是同一天的情況 if startiswork = 1 then -- 工作日減去1天 set workdaynum = workdaynum - 1; -- 小于上午上班時間,計算 一天 if @timestart <= @monworkstart then set interval_minute = interval_minute 480; -- 處于上午工作時間,計算 開始時間與上午下班時間間隔 半天 elseif @timestart <= @monworkend then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @monworkend)) 240; -- 處于午休區間,計算 半天 elseif @timestart <= @noonworkstart then set interval_minute = interval_minute 240; -- 處于下午工作時間,計算 開始時間與下午下班時間間隔 elseif @timestart <= @noonworkend then set interval_minute = interval_minute timestampdiff(minute, starttime, concat(@startdate,' ', @noonworkend)); end if; end if; if endiswork = 1 then -- 工作日減去1天 set workdaynum = workdaynum - 1; -- 小于上午上班時間,計算 0 if @timeend <= @monworkstart then set interval_minute = interval_minute 0; -- 處于上午工作時間,計算 上午上班時間與結束時間間隔 elseif @timeend <= @monworkend then set interval_minute = interval_minute timestampdiff(minute, concat(@enddate,' ', @monworkstart), endtime); -- 處于午休時間,計算 半天 elseif @timeend <= @noonworkstart then set interval_minute = interval_minute 240; -- 處于下午工作時間,計算 半天 下午上班時間與結束時間間隔 elseif @timeend <= @noonworkend then set interval_minute = interval_minute 240 timestampdiff(minute, concat(@enddate,' ', @noonworkstart), endtime); -- 大于下午下班時間,計算 一天 elseif @timeend > @noonworkend then set interval_minute = interval_minute 480; end if; end if; end if; -- 計算得到最終的工作分鐘數 return interval_minute workdaynum * 480; end;

效果檢查

我們使用4月的日曆進行測試,測試結果如下:

mysql中求大于某個日期的數據(工作時工作日函數)3

性能檢查

實測5萬5千條記錄,耗時1分10秒,當然這是在本機docker上的mysql跑的結果,本機的配置比較低,CPU為i5-8250U,mysql最大内存1G

結束語

函數在數據量少的情況下還是可以使用,多了就會占用寶貴的數據庫資源,得不償失,如果大家有更好的辦法,歡迎留言讨論!

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
各個電子表合并方法(多表合并還可以用這招)
各個電子表合并方法(多表合并還可以用這招)
  私信回複關鍵詞【學一招】,一次性獲取Excel小技巧合集!助你成為高效職場人!   兩張主字段相同的表格,要把内容合并到一張表格内,這個場景你熟不熟悉?   這位同學就有這樣的問題:      他的兩個數據表是這樣的:      他想要把兩個表要合并成一張表,即:   在一張表中顯示完整的學号、姓名、班級及各科的考試成績。   01問題分析   其中一張...
2026-05-14
攝影師該怎麼提高收入(從助理變為攝影師得多長時間)
攝影師該怎麼提高收入(從助理變為攝影師得多長時間)
  新手提問:學攝影 從助理變為攝影師得多長時間?成為攝影師後的初期工資大概是多少?攝影師在公司上班有35歲的年齡限制嗎?就像IT行業有年齡限制?一般來說 在一線或新一線城市 助理半年後的薪資是多少 一年後是多少 兩年後是多少?      回答:首先,先說從助理變成攝影師需要多長時間,這個因人而異,這個“人”并不是因為你自己,而是說你的際遇如何,遇到什麼樣的...
2026-05-14
漳浦縣領導檢查高考考點(潮陽區1.7萬多學子赴高考)
漳浦縣領導檢查高考考點(潮陽區1.7萬多學子赴高考)
     6月7日,2022年全國普通高考拉開序幕,潮陽區17297名考生們懷揣夢想,奔赴人生中一場重要的“大考”。上午,區長尤朝東帶隊到潮陽一中、潮陽實驗學校等高考考點,通過電子監控系統巡察考場秩序。他強調,各地各單位要用心用情用功,抓嚴抓細抓實平安高考和疫情防控各項工作,确保高考平安、順利。      潮陽一中   由區長尤朝東帶隊的巡考組先後來到潮陽一...
2026-05-14
樸叙俊外号社長(樸叙俊貴人徐睿知老闆)
樸叙俊外号社長(樸叙俊貴人徐睿知老闆)
  金秀賢退伍後首部新作《雖然是精神病但沒關系》,片場就有國民妹妹IU李知恩、樸叙俊,以及仍在軍中服役的好友李洪基獻上應援咖啡車,為他加油打氣。金秀賢出道至今13年,個性親切、幽默的他,在韓國演藝圈的人緣十分好,經常因拍戲和劇中演員成為好友,就連高冷魔女徐睿知都被他延攬到自家的經紀公司。      下面來起底金秀賢的演藝圈的好友網。   伯樂裴勇俊  金秀賢...
2026-05-14
互聯網運營崗值得做嗎(互聯網運營崗工作都有哪些)
互聯網運營崗值得做嗎(互聯網運營崗工作都有哪些)
  每一個進入職場的人或者每一次跳槽的人,都會遇到的幾個問題:我想做什麼工作?我适合做什麼工作?我能做什麼工作?這都映射出對自己的審視和對工作的思考。   說到工作,從互聯網誕生到今天移動互聯網的盛行,伴随着無數工作的交替和工作崗位的叠代。尤其是在互聯網中扮演着重要角色的運營,更是崗位繁多稱呼不定。使得想從事運營工作的人不知該如何選擇,更讓很多初入運營工作1...
2026-05-14
Copyright 2023-2026 - www.tftnews.com All Rights Reserved