为女票写的计算工作时间的SQL
排除非工作时间、非工作日后,计算工作时间,代码如下:
-- 删除函数
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 intnum int(255) DEFAULT 0;
DECLARE decimalnum decimal(32,4) DEFAULT 0.000;
DECLARE workStartTimeHour decimal(32,4) DEFAULT 0.000;
DECLARE workEndTimeHour decimal(32,4) DEFAULT 0.000;
DECLARE currentDay int(10) DEFAULT 0;
DECLARE tempTimeHour decimal(32,4) DEFAULT 0.000;
-- DECLARE temp varchar(2048) DEFAULT ''; -- deal starttime and endtime is nonworkdays
SET startDate = (CASE WHEN weekday(startDate)=5 THEN concat(date(timestampadd(day,2,startDate)),' ',@workStartTime) WHEN weekday(startDate)=6 THEN concat(date(timestampadd(day,1,startDate)),' ',@workStartTime) ELSE startDate END);
SET endDate = (CASE WHEN weekday(endDate)=5 THEN concat(date(timestampadd(day,-1,endDate)),' ',@workEndTime) WHEN weekday(endDate)=6 THEN concat(date(timestampadd(day,-2,endDate)),' ',@workEndTime) ELSE endDate END);
-- SET temp = concat(temp,' ',startDate,';',endDate);
if startDate < endDate then
-- deal starttime and endtime is nonworktime
if time(startDate)<=@workStartTime THEN
SET startDate = concat(date(startDate),' ', @workStartTime);
elseif date(startDate) < date(endDate) and time(startDate)>@workEndTime then
SET startDate = concat(date(date_add(startDate, interval 1 day)),' ',@workStartTime);
end if; if time(endDate)>=@workEndTime then
SET endDate = concat(date(endDate),' ',@workEndTime);
elseif date(startDate) < date(endDate) and time(endDate)<@workStartTime then
SET endDate = concat(date(date_add(endDate, interval -1 day)),' ',@workEndTime);
end if; -- calculate time diff
SET decimalnum = (minute(endDate)*60+second(endDate)-minute(startDate)*60-second(startDate))/3600; end if; -- calculate work time second
SET workStartTimeHour = hour(@workStartTime)+minute(@workStartTime)/60+second(@workStartTime)/3600;
SET workEndTimeHour = hour(@workEndTime)+minute(@workEndTime)/60+second(@workEndTime)/3600; -- WHILE (floor((unix_timestamp(endDate) - unix_timestamp(startDate))/3600) > 0) DO
WHILE ((floor(unix_timestamp(endDate)/3600) - floor(unix_timestamp(startDate)/3600)) > 0) DO
SET tempTimeHour = hour(startDate)+minute(startDate)/60+second(startDate)/3600; if workStartTimeHour <= tempTimeHour and tempTimeHour < workEndTimeHour then
-- SET temp = concat(temp,' ',tempTimeHour,';');
SET intnum = (CASE WHEN weekday(startDate)=5 or weekday(startDate)=6 then intnum ELSE intnum+1 END);
end if;
SET startDate = timestampadd(hour,1,startDate);
END WHILE; SET decimalnum = intnum + decimalnum;
-- concat(decimalnum,';',workStartTimeHour,' ',workEndTimeHour,' ',intnum,';;;',temp);
RETURN decimalnum;
END
/ -- select calculateWorkingTime('2017-02-17 07:30:00','2017-02-21 17:39:00');
select transport_id,create_at1,create_at2,create_at3, calculateWorkingTime(create_at1,create_at2), calculateWorkingTime(create_at2,create_at3),calculateWorkingTime(create_at1,create_at3) from newTable; select transport_id,calculateWorkingTime(create_at1,create_at2) from newTable;
说明:第一次实现这种需求,当初写的时候又比较赶,写完后,发现,虽然功能实现了,但还有好多地方可以调优
女票是搞数据运营的,经常需要统计员工的工作时间;听女票说,这段SQL代码统计时好像有些问题,但还没来的急分析原因呢;女票又有新需求来了,不仅需要将非工作时间、非工作日去掉,还需要将节假日去掉 我将上面代码重构,实现想要功能(重构后的代码就不放出了)
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
为女票写的计算工作时间的SQL的更多相关文章
- 为女票写的计算工作时间的SQL(二)
将非工作时间.非工作日.节假日去掉,计算工作时间,如下: 一.实现 -- 节假日表 CREATE TABLE Holiday ( id ) NOT NULL, DATE ), flag ) , PRI ...
- 写出易调试的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.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...
- 函数计算 Python 连接 SQL Server 小结
python 连接数据库通常要安装第三方模块,连接 MS SQL Server 需要安装 pymssql .由于 pymsql 依赖于 FreeTDS,对于先于 2.1.3 版本的 pymssql,需 ...
- 如何写出性能好的sql
开发人员是很少注意SQL对数据库性能影响的重要性的,大多程序员都会认为SQL是比较简单的,需要的时候查查手册就可以了,很少有深究的. 这样的观念对大型系统的开发是致命的,需要纠正这样的观念. 造成这样 ...
- 写了一个复杂的sql语句
$sp_sql = "select sp_ProductNo, sp_ProductName,sp_Standard,sp_Unit,sum(sp_Amount) as amount fro ...
随机推荐
- getline函数(精华版)
在我的印象中,getline函数经常出现在自己的视野里,模糊地记得它经常用来读取字符串 .但是又对它的参数不是很了解,今天又用到了getline函数,现在来细细地总结一下: 首先要明白设计ge ...
- 安装hadoop2.7.3
hadoop3与hadoop2.x的变化很大,hadoop3很多东西现在做起来太麻烦了,这里先安装hadoop2.7.3 此贴学习地址http://www.yiibai.com/t/mapreduce ...
- 使用 Gradle 编译 Java 项目时报错: Could not find Tools.jar
在使用Android studio进行编译成jar的时候,遇到Gradle 编译错误,听前辈们说是jdk的版本不对,于是乎就更新了一下jdk, 然而可能是我重新安装jdk的时候改变了安装路径, 在pr ...
- [转]Installing Memcached on Windows
Installing Memcached on Windows 原文链接https://commaster.net/content/installing-memcached-windows Sub ...
- [codevs]1087麦森数
题目 这个题在noiOJ上是分治专题,这个题包括了很多,求位数,高精度乘,快速幂. 那么单独把这个高精度拿出来做一个自定义函数即可 一.求位数 显而易见,既然是2进制的就是log2X,是10进制就是l ...
- Oracle中碰到的函数和关键字收集
一.时间处理函数 trunc(sysdate) 返回日期 to_date() to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') to_number() 转为数字 二.字 ...
- Android ContentProvider详解
1.概述 ContentProvider以Uri的形式对外提供数据,允许其他应用程序访问或者修改数据.也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过 ...
- ConcurrentHashMap源码解析
转自:http://www.iteye.com/topic/344876 ConcurrentHashMap是Java 5中支持高并发.高吞吐量的线程安全HashMap实现. 实现原理 锁分离 (Lo ...
- MyBatis和Hibernate相比,优势在哪里?
1.开发对比开发速度 hibernate的真正掌握要比Mybatis来得难些.Mybatis框架相对简单很容易上手,但也相对简陋些.个人觉得要用好Mybatis还是首先要先理解好Hibernate. ...
- 进制转换,杭电0j-2031
进制转换,杭电0j-2031原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=2031 [Problem Description] 输入一个十进制数N,将它 ...