首页
/
每日頭條
/
職場
/
mysql中求大于某個日期的數據
mysql中求大于某個日期的數據
更新时间:2024-11-11 22:41:52
前言

最近小編在項目中遇到需要查詢某個工單還有多少剩餘處理時間的需求,并且要按照工作時的計算方式,對剩餘處理時間按升序排列,如果是對查詢出來的工單進行剩餘時間計算,那麼在程序中就能夠完成,但偏偏要求需要進行排序,這可就難了,因為數據表内記錄超過百萬,放在程序中處理肯定會溢出,最終還是選擇加個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
推荐阅读
林生斌現任妻子分享生活(僅用6月就從實習生)
林生斌現任妻子分享生活(僅用6月就從實習生)
  林生斌的事情發酵8天後,他終于出來回應了。一口氣發了5條動态,字裡行間都是在說自己很懷念逝去的妻兒、讓大家不要傷害他現在的妻兒、他對他嶽父嶽母很好,沒有這幾天傳的那麼糟。      在這幾條動态中,關于林生斌的現任妻子小樂的動态,引起了小8的注意。這些天,關于小樂的傳言,說什麼的都有,有說她是小三上位的,有說她跟林生斌早就認識的,還有說她跟保姆是親戚的。...
2024-11-11
17款奧迪q5豪華新圖解(18款奧迪Q5現已上市喜歡的老闆們可以關注一下)
17款奧迪q5豪華新圖解(18款奧迪Q5現已上市喜歡的老闆們可以關注一下)
     新款奧迪Q5在外觀上整體保持了老款車型的設計風格,隻是在細節方面做出了相應的調整。車頭方面,采用最新的六邊形設計的一體式進氣格栅體現在奧迪Q系列最新的家族特征;頭燈采用奧迪家族最新的設計,擁有極高的辨識度;前保險杠更富于立體感,下方進氣格栅配以更加動感的橫向飾條。尾部改動不大,主要集中在燈組内的設計以及排氣造型方面。         2018款奧迪...
2024-11-11
天堂2血盟什麼職業最簡單(血盟職業不知道怎麼選)
天堂2血盟什麼職業最簡單(血盟職業不知道怎麼選)
  《天堂2:血盟》是NCSOFT國内唯一首授權的手遊,而NCSOFT是《天堂2》的開發工作室,《天堂2:血盟》和《天堂2》的關心自然不用小編我多說,雖然《天堂2》是一個老IP,但是實際上遊戲中的萌新還是不少的,對于萌新來說,在《天堂2:血盟》中最先要面對的就是選擇職業,面對《天堂2:血盟》的9個職業,應該怎麼選,就成了衆多萌新玩家需要面對的問題,今天小編就...
2024-11-11
安徽财貿職業學院高考曆年錄取分(安徽财貿職業學院近幾年投檔分數線)
安徽财貿職業學院高考曆年錄取分(安徽财貿職業學院近幾年投檔分數線)
  安徽财貿職業學院是安徽省人民政府批準設置、教育部備案的公辦全日制普通高等學校,為安徽省示範性高職院校,國家優質專科高等職業院校立項建設單位,納貝斯特教育統計的數據顯示,該校近幾年來的錄取分數線都相對較高,一般都在360分以上,下面是該校2018年、2019年面向安徽省内,各專業最低錄取分數線及最低位次,供考生作為報考參考。   安徽财貿職業學院2019年...
2024-11-11
鐘淑慧個人寫真(香港風月女星鐘淑慧)
鐘淑慧個人寫真(香港風月女星鐘淑慧)
  #頭條創作挑戰賽#   對于鐘淑慧,相比于之前提到的那些風月女星,她的人氣不高,走紅程度也不及前面的幾位,但說到香港風月女星,小編還是想談談鐘淑慧,不為别的,隻是因為她的經曆也堪稱是比電影還精彩的故事了。      鐘淑慧   鐘淑慧出生于1964年,祖籍是廣東梅州。與其他女藝人的走紅相似但是卻又有着極大的不同,鐘淑慧本人是環球小姐出身的。在那個年代,選...
2024-11-11
Copyright 2023-2024 - www.tftnews.com All Rights Reserved