为女票写的计算工作时间的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查询语句所导致的注入.防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据 ...
随机推荐
- DataBindings的用法
在C#操作数据库过程中,针对一般的文本控件,比如TextBox,Label等,我们赋值直接使用类似TextBox.Text=****的方式来进行,这种方式从某种意义上来说的确是最简便的方式,但是对于复 ...
- java学习笔记7--抽象类与抽象方法
接着前面的学习: java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) jav ...
- Easyui 判断某个Div 里的表单项是否验证通过.
var isValid = $("#divId").Form("validate"); if( isValid ){ alert("验证通过" ...
- 让Netty入门变得简单
让Netty入门变得简单 https://mp.weixin.qq.com/s/MBnbLmCmFJo0QK9WNwXrXQ 如果先启动nettyClient就不会有nettyServer输出了: p ...
- Google POI下载工具破解之路
我是GIS初学者,爱好二次开发,像初恋一样.最近对编译感兴趣,每当成功获取一点信息,就有一种快感,感觉马上就要成功了……其实,还早! 01.初次反编译 今天在微创业工作室找到了Google POI下载 ...
- TCP客户/服务器程序实例——回射服务器
目录 客户/服务器程序源码 POSIX信号处理 POSIX信号语义 处理SIGCHLD信号 处理僵死进程 处理被中断的系统调用 wait和waitpid函数 wait和waitpid函数的区别 网络编 ...
- Unity Web前端研究
原地址:http://blog.csdn.net/libeifs/article/details/7200630 开发环境 Window7 Unity3D 3.4.1 MB525defy Andro ...
- cocos2d-x CCScrollView 源代码分析
版本号源代码来自2.x,转载请注明 另我实现了能够循环的版本号http://blog.csdn.net/u011225840/article/details/31354703 1.继承树结构 能够看出 ...
- OFBiz:组件装入位置
默认的,OFBiz会在framework.applications.specialpurpose.hot-deploy这几个目录寻找组件,在themes目录中寻找主题.OFBiz是通过framewor ...
- 微信小程序—智能小蜜(基于智能语义解析olami开放平台)
概述 该程序支持功能有查天气.查诗词.查百科.算算术.查日历.看笑话.看故事.聊天等,通过用户输入语句智能解析用户意图输出相应答案. 详细 代码下载:http://www.demodashi.com/ ...