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

一、实现

-- 节假日表
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. 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)

    一般的我们喜欢这样对对象赋值: Person p1;Person p2=p1; classT object(another_object), or    A a(b); classT object = ...

  2. 高性能WEB开发:深入理解页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

  3. vi命令整理

    vi命令整理 u 撤销上一次操作 ctrl+r 恢复上一次操作 : 跳转至第1行 :$ 跳转至最后一行 ctrl+f 向文章末尾翻页 ctrl+b 向文章开始翻页 yy 复制一行 p 粘贴刚刚复制第一 ...

  4. tomcat7的数据库连接池tomcatjdbc的25个优势

    tomcat的JDBC连接池org.apache.tomcat.jdbc.pool更换或替代吗Apache Commons DBCP连接池. 为什么我们须要一个新的连接池? 这里有几个原因: 1.DB ...

  5. redis在linux下安装并測试(在spring下调用)

    官网帮助文档例如以下 Installation Download, extract and compile Redis with: $ wget http://download.redis.io/re ...

  6. 给你的webstorm添加快速生成注释得快捷键

    打开File----setting-map-搜搜"fix doc"

  7. GTID数据库备份

    rhel6系统中,mysql 5.6复制新特性下主从复制配置[基于GTID] 1.mysql5.6在复制方面的新特性: (1).支持多线程复制:事实上是针对每个database开启相应的独立线程,即每 ...

  8. 使用ionic中的侧边栏以及angularjs中广播的使用

    接着之前的ionic的例子 查看例子:我的第一段ionic代码 demo3.html(黄底内容为增加或修改的内容) <!DOCTYPE html> <html ng-app=&quo ...

  9. 本地计算机上的OracleOraDb11g_home2TNSListener服务启动又停止了。一些服务自动停止,如果他们没有什么可做的 .

    一.问题 本地计算机上的OracleOraDb10g_home1TNSListener 服务启动又停止了 二.问题描述 Oracle:本地计算机上的OracleOraDb10g_home1TNSLis ...

  10. 老生常谈,HashMap的死循环(转)

    本文转自掘金占小狼:用于理解HashMap为什么线程不安全,不能用于并发. 地址就在下文: 问题 由于HashMap并非是线程安全的,所以在高并发的情况下必然会出现问题,这是一个普遍的问题,虽然网上分 ...