为女票写的计算工作时间的SQL
Posted 刘超
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为女票写的计算工作时间的SQL相关的知识,希望对你有一定的参考价值。
将非工作时间、非工作日、节假日去掉,计算工作时间,如下:
一、实现
-- 节假日表 CREATE TABLE Holiday ( id INT(10) DEFAULT 0 NOT NULL, DATE DATETIME(6), flag INT(1) DEFAULT 0, PRIMARY KEY (id) ); -- 向节假日表中插入数据 INSERT INTO Holiday (id, date, flag) VALUES (1, \'2017-04-01 00:00:00\', \'1\'); INSERT INTO Holiday (id, date, flag) VALUES (2, \'2017-04-02 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (3, \'2017-04-03 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (4, \'2017-04-04 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (5, \'2017-04-29 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (6, \'2017-04-30 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (7, \'2017-05-01 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (8, \'2017-05-27 00:00:00\', \'1\'); INSERT INTO Holiday (id, date, flag) VALUES (9, \'2017-05-28 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (10, \'2017-05-29 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (11, \'2017-05-30 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (12, \'2017-09-30 00:00:00\', \'1\'); INSERT INTO Holiday (id, date, flag) VALUES (13, \'2017-10-01 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (14, \'2017-10-02 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (15, \'2017-10-03 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (16, \'2017-10-04 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (17, \'2017-10-05 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (18, \'2017-10-06 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (19, \'2017-10-07 00:00:00\', \'0\'); INSERT INTO Holiday (id, date, flag) VALUES (20, \'2017-10-08 00:00:00\', \'0\'); -- 删除函数 DROP FUNCTION IF EXISTS calculateWorkingTime; set @workStartTime=\'09:30:00\'; set @workEndTime=\'18:30:00\'; -- 创建函数,该函数用于计算去掉非工作时间、非工作日、节假日后的工作时间 --/ CREATE FUNCTION calculateWorkingTime(startDate datetime,endDate datetime) RETURNS decimal(32,4) BEGIN DECLARE decimalnum decimal(32,4) DEFAULT 0.000; DECLARE holidayflag int(255) DEFAULT -1; DECLARE holidaydate varchar(128) DEFAULT \'\'; DECLARE startFlag boolean DEFAULT True; DECLARE starttime time; DECLARE endtime time; WHILE (date(startDate) <= date(endDate)) DO select flag,date into holidayflag,holidaydate from Holiday where date(date)=date(startDate); if holidayflag > -1 THEN if holidayflag > 0 then if startFlag then SET starttime = (case when time(startDate) > time(@workStartTime) then (case when time(startDate) <= time(@workEndTime) then time(startDate) else time(@workEndTime) end) else time(@workStartTime) end); SET startFlag = False; else SET starttime = time(@workStartTime); end if; if date(startDate) = date(endDate) then SET endtime = (case when time(endDate) < time(@workEndTime) then (case when time(endDate) >= time(@workStartTime) then time(endDate) else time(@workStartTime) end) else time(@workEndTime) end); else SET endtime = time(@workEndTime); end if; SET decimalnum = decimalnum + (hour(endtime) - hour(starttime)) + (minute(endtime)*60+second(endtime)-minute(starttime)*60-second(starttime))/3600; elseif startFlag then SET startFlag = False; end if; else if 0 <= weekday(startDate) and weekday(startDate) <=4 THEN if startFlag then SET starttime = (case when time(startDate) > time(@workStartTime) then (case when time(startDate) <= time(@workEndTime) then time(startDate) else time(@workEndTime) end) else time(@workStartTime) end); SET startFlag = False; else SET starttime = time(@workStartTime); end if; if date(startDate) = date(endDate) then SET endtime = (case when time(endDate) < time(@workEndTime) then (case when time(endDate) >= time(@workStartTime) then time(endDate) else time(@workStartTime) end) else time(@workEndTime) end); else SET endtime = time(@workEndTime); end if; SET decimalnum = decimalnum + (hour(endtime) - hour(starttime)) + (minute(endtime)*60+second(endtime)-minute(starttime)*60-second(starttime))/3600; elseif startFlag then SET startFlag = False; end if; end if; -- init Param SET holidayflag = -1; SET holidaydate = \'\'; SET startDate = timestampadd(day,1,startDate); END WHILE; RETURN decimalnum; END
二、测试
CREATE TABLE newTable ( transport_id INT(100) NOT NULL, col2 VARCHAR(100), col3 VARCHAR(100), col4 VARCHAR(100) ); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (166477, \'2017-04-01 10:00:56\', \'2017-04-08 10:30:58\', \'2017-04-23 17:23:32\'); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (167031, \'2017-09-30 11:14:21\', \'2017-10-09 13:35:40\', \'2018-11-13 12:52:37\'); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (166487, \'2017-05-24 09:53:23\', \'2017-05-24 10:53:53\', \'2017-05-26 12:53:53\'); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (166489, \'2017-05-24 09:29:59\', \'2017-05-25 12:53:53\', \'2017-05-26 12:53:53\'); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (166490, \'2017-05-24 09:30:01\', \'2017-05-25 23:53:53\', \'2017-05-26 12:53:53\'); INSERT INTO newTable (transport_id, col2, col3, col4) VALUES (166491, \'2017-05-24 09:30:00\', \'2017-05-25 12:23:00\', \'2017-05-26 12:53:53\');
三、效果
select col2,col3,col4,calculateWorkingTime(col2,col3),calculateWorkingTime(col3,col4) from newTable;
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。
本文版权归作者,禁止转载,否则保留追究法律责任的权利。
以上是关于为女票写的计算工作时间的SQL的主要内容,如果未能解决你的问题,请参考以下文章
懂Python的女票太可怕,一行代码窥探了我的浏览器历史秘密...
spring的自动装配,骚话@Autowired的底层工作原理