为女票写的计算工作时间的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查询语句所导致的注入.防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据 ...
随机推荐
- RV BaseRecyclerViewAdapterHelper 总结 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 【Linux】shell字符串分割、数组访问、条件判断
参考资料: shell字符串分割再循环:http://www.shangxueba.com/jingyan/1633455.html linux shell中 if else以及大于.小于.等于逻辑表 ...
- FrameWork数据权限浅析4之基于多维度配置表实现行级数据安全
日子过得好苦逼,我过的很好,只是缺少¥.时间在变,而问题始终未变,你解不解决它都在那里一动不动.不知不觉已经发现手机的中央,电脑的右下角已经出现了201411的字样,突然从桌子上爬起来,差点忘记了自己 ...
- [简谈]绕过HR破门而入的求职智慧
以往我们在网上看到的非常多求职文章或指导性纲领,譬如啥自信.做功课.良好形象.华丽的简历.工作经验.口才啥的,事实上到了21世纪尤其是互联网快速发展的今天,前面这些技巧就显得无比空洞: 1.由于自信谁 ...
- TortoiseSVN 源代码下载
SVN的客户端软件TortoiseSVN http://tortoisesvn.tigris.org/ 这是我采用的 TortoiseSVN 的官方网站,页面上的两只小乌龟真的很好看. 目前最新的版本 ...
- (剑指Offer)面试题4:替换空格
题目: 请实现一个函数,把字符串中的每个空格替换成“%20”,例如输入“We are happy”,则输出“We%20are%20happy”. 思路: 背景: 在网络编程中,如果URL参数中含有特殊 ...
- grid control 11.1.0.1 安装指南
grid control 11.1.0.1 安装指南 废话少说,进入正题 系统版本号 [root@gridcontrol ~]# lsb_release -a LSB Version: :bas ...
- 05-maven学习-构建web项目
1,新增maven项目 然后输入相应包名,项目名,创建如下项目 发现以上有报错,需要进行如下操作: 下面文章转载自:http://blog.csdn.net/zhshulin/article/deta ...
- MySQL中group_concat函数
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) .MySQL中group_concat函数完整的语法如下:group_c ...
- Ubuntu 分区方案参考
2011-10-25 10:09 对于初次接触的一般用户(包括双系统用户): / 5-10G(玩玩的话5G就够,长期使用的话推荐10G) /usr 5-10 ...