为女票写的计算工作时间的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', '');
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(二)的更多相关文章
- 为女票写的计算工作时间的SQL
排除非工作时间.非工作日后,计算工作时间,代码如下: -- 删除函数 DROP FUNCTION IF EXISTS calculateWorkingTime; set @workStartTime= ...
- 写出易调试的SQL(修订版)
h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...
- 写出易调试的SQL
h4 { background: #698B22 !important; color: #FFFFFF; font-family: "微软雅黑", "宋体", ...
- 写出易调试的SQL—西科软件
1.前言 上篇 写出易调试的SQL , 带来了一些讨论, 暴露了不能重用执行计划和sql注入问题, 十分感谢园友们的建议 . 经过调整后 ,将原来的SQLHelper 抓SQL 用做调试环境用, 发布 ...
- 可写的计算监控(Writable computed observables)
新手可忽略此小节,可写依赖监控属性真的是太advanced了,而且大部分情况下都用不到. 一般情况下,计算监控的值是通过其他监控属性的值计算出来的,因此它是只读的.这个看似很奇怪,我们有什么办法可以让 ...
- Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控
2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...
- 7.26实习培训日志-Oracle SQL(二)
Oracle SQL(二) 条件表达式 CASE 语句 或者DECODE 函数,两者均可实现 IF-THEN-ELSE 的逻辑,相比较而言,DECODE 更加简洁 SELECT last_name , ...
- jQuery写省级联动列表,创造二维数组,以及如何存/调用二维数组中的数据
jQuery写省级联动列表,创造二维数组来存放数据,然后通过each来遍历调用,通过creatTxtNode创建文本节点,通过createElement创建标签option,在通过append将文本写 ...
- [转]sql二次注入
01 二次注入原理 二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入.防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据 ...
随机推荐
- MapReduce API 基本概念
在正式分析新旧 API 之前, 先要介绍几个基本概念. 这些概念贯穿于所有 API 之中,因此, 有必要单独讲解. 1.序列化 序列化是指将结构化对象转为字节流以便于通过网络进行传输或写入持久存储的过 ...
- java学习笔记4--对象的初始化与回收
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note4.html,转载请注明源地址. 1.对象初始化和回收 对象初始化 系统在生成对象时,会 ...
- 【Python】Python Mako模板使用
参考资料: Mako Templates for Python官网:http://www.makotemplates.org/ Python模板库Mako的用法:http://my.oschina.n ...
- sql server 批量导出存储过程
sys.syscomments:包含数据库中每个视图.规则.默认值.触发器.CHECK 约束.DEFAULT 约束和存储过程的项.text 列包含原始的 SQL 定义语句.(简单点说,这个系统表存储了 ...
- 华为P6-C00电信版,刷机总是失败? FAIL
关于这个刷机失败的问题,我只想说一点: 华为P6-C00电信版刷机时,不是任意版本都可以刷到任意版本的.我只往上刷过,那就是华为的升级文档中有说明:“只有以下版本才可以升级到此版本”. 如果你的手机的 ...
- 【转】非教育网中IPv4网络访问IPv6资源
1. 背景知识 随着个人电脑.移动终端.乃至物联网的不断发展,有很大的IP地址需求.由于IPv4协议设计时没有料到日后网络会如此发达,IPv4网络中的IP数量相对今天的需求来说,显得捉襟见肘.加上IP ...
- Jquery—Jquery中的(function($){...})(jQuery)
当你第一眼看到"(function($){...})(jQuery)"的时候.你有什么感觉?呵呵呵,我当时还是止不住的从心底里骂了一句--操,这他妈什么劳什子.时过境迁,对于如今无 ...
- 揭秘ThreadLocal(转)
转载自:掘金大闲人柴毛毛博客. ThreadLocal是开发中最常用的技术之一,也是面试重要的考点.本文将由浅入深,介绍ThreadLocal的使用方式.实现原理.内存泄漏问题以及使用场景. Thre ...
- 用vue开发顶端粘滞效果的页面
概述 通常一个长的页面,需要滚动浏览,有部分重要信息会随着滚动而看不见,因此需要粘滞在顶端,而又不影响滚动浏览,这个demo基于vue2,实现这个需求. 详细 代码下载:http://www.demo ...
- findlibrary returned null产生的联想,Android ndk开发打包时我们应该怎样注意平台的兼容(x86,arm,arm-v7a)
非常多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,由于某种原因,so没有打包到apk中.以下浅析下引起该错误的原因以及平台兼容性问题. A ...