将非工作时间、非工作日、节假日去掉,计算工作时间,如下:

一、实现

-- 节假日表
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', '');
INSERT INTO Holiday (id, date, flag) VALUES (2, '2017-04-02 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (3, '2017-04-03 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (4, '2017-04-04 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (5, '2017-04-29 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (6, '2017-04-30 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (7, '2017-05-01 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (8, '2017-05-27 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (9, '2017-05-28 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (10, '2017-05-29 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (11, '2017-05-30 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (12, '2017-09-30 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (13, '2017-10-01 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (14, '2017-10-02 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (15, '2017-10-03 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (16, '2017-10-04 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (17, '2017-10-05 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (18, '2017-10-06 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (19, '2017-10-07 00:00:00', '');
INSERT INTO Holiday (id, date, flag) VALUES (20, '2017-10-08 00:00:00', ''); -- 删除函数
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(二)的更多相关文章

  1. 为女票写的计算工作时间的SQL

    排除非工作时间.非工作日后,计算工作时间,代码如下: -- 删除函数 DROP FUNCTION IF EXISTS calculateWorkingTime; set @workStartTime= ...

  2. 写出易调试的SQL(修订版)

    h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...

  3. 写出易调试的SQL

    h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...

  4. 写出易调试的SQL—西科软件

    1.前言 上篇 写出易调试的SQL , 带来了一些讨论, 暴露了不能重用执行计划和sql注入问题, 十分感谢园友们的建议 . 经过调整后 ,将原来的SQLHelper 抓SQL 用做调试环境用, 发布 ...

  5. 可写的计算监控(Writable computed observables)

    新手可忽略此小节,可写依赖监控属性真的是太advanced了,而且大部分情况下都用不到. 一般情况下,计算监控的值是通过其他监控属性的值计算出来的,因此它是只读的.这个看似很奇怪,我们有什么办法可以让 ...

  6. Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控

    2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...

  7. 7.26实习培训日志-Oracle SQL(二)

    Oracle SQL(二) 条件表达式 CASE 语句 或者DECODE 函数,两者均可实现 IF-THEN-ELSE 的逻辑,相比较而言,DECODE 更加简洁 SELECT last_name , ...

  8. jQuery写省级联动列表,创造二维数组,以及如何存/调用二维数组中的数据

    jQuery写省级联动列表,创造二维数组来存放数据,然后通过each来遍历调用,通过creatTxtNode创建文本节点,通过createElement创建标签option,在通过append将文本写 ...

  9. [转]sql二次注入

    01 二次注入原理 二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入.防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据 ...

随机推荐

  1. TensorFlow进阶(四)---名称域和共享变量

    变量作用域 tensorflow提供了变量作用域和共享变量这样的概念,有几个重要的作用. 让模型代码更加清晰,作用分明 变量作用域域 通过tf.variable_scope(<scope_nam ...

  2. swfupload js中 file 对象的属性

    name=3cc68cfc60b87e6dd6887d8a.jpg modificationdate=Wed   Apr 21 15:48:30 UTC+0800 2010 filestatus=-1 ...

  3. win10 修改cmd终端编码格式为utf8

    最近在使用ssh 连接服务器时,好多中文显示为乱码,查明原因,是因为自己cmd终端编码给是为gbk,而服务器编码格式为utf8,所以需要修改cmd终端编码格式为utf8,但是网上看到好多解决方案是 1 ...

  4. KVM&amp;Libvirt基本概念及开发杂谈

    导读 大家好,本次肖力分享的主题是KVM&Libvirt基本概念及开发杂谈,内容有些凌乱松散,主要基于自己早期整理的笔记内容和实践感悟,有些内容难免有失偏颇,望见谅.前面先介绍下需要了解的基本 ...

  5. 【实践】简洁大方的summernote 富文本编辑器插件的用发——小技巧

    前面说到summernote 的上传,可是我要知道怎么获取内容呀,很简单调用一下函数便可: 获取内容: $("#user-work-content").summernote(&qu ...

  6. [Transducer] Step by Step to build a simple transducer

    Transducers are composable algorithmic transformations. They are independent from the context of the ...

  7. [ES6] 01. Intro to ES6 and traceur compiler

    ---恢复内容开始--- ES6 is ECMAScript version 6, which JavaScript is based on. The next version of JavaScri ...

  8. XPath查找节点值示例

    下面一个XML文档,需要找到粗体部分文字: <?xml version='1.0' encoding='utf-8'?> <rep sts="OK" a=&quo ...

  9. 如何使用angularjs实现抓取页面内容

    <html ng-app="myApp"> <head> <title>angularjs-ajax</title> <scr ...

  10. FFmpeg视频处理必备

    http://ffmpeg.org/官网 A complete, cross-platform solution to record, convert and stream audio and vid ...