一个关于考勤统计的sql研究
在这里,我们要做一个简单的员工考勤记录查询系统的后台数据库。业务需求如下所示:
解决这个问题的时候本来考虑的是在考勤信息记录表中按照日期对考勤信息进行分组,然后取每组中上班时间(att_work_datatime)的最小值,但是后来几经折腾发现group by只能实现分组,而order by只能实现组外排序,因此这个方法只能放弃。再三考虑了一下,可以在分组之前先对表中att_work_datatime列中的所有值进行升序排序后生成一个临时表,然后对这个临时表中的att_work_datatime按照日期再分组,这样对att_work_datatime列按照日期group by之后取的就是每天上班打卡最早的人,我们从attendance_info_table(考勤信息表)表中查询出出每天上班时间最早的人的编号、上班时间和下班时间,sql语句如下:
from

order by att_work_datatime) as tmp

from employee_info_table as em ,
(select id,att_work_datatime,after_work_datatime,emp_id
from attendance_info_table
where att_work_datatime is not null
order by att_work_datatime )
as tmp
where em.id=tmp.emp_id
group by Date(att_work_datatime)
select eit.*, ait.att_work_datatimefrom attendance_info_table ait, employee_info_table eitwhere ait.emp_id = eit.id and ait.att_work_datatime in(select min(att_work_datatime)from attendance_info_tablewhere att_work_datatime is not nullgroup by Date(att_work_datatime))order by ait.att_work_datatime asc;
from employee_info_table as em ,
(select id,att_work_datatime,after_work_datatime,emp_id
from attendance_info_table
where att_work_datatime is not null
order by att_work_datatime desc)
as tmp
where em.id=tmp.emp_id
group by Date(att_work_datatime)
select eit.*, ait.att_work_datatimefrom attendance_info_table ait, employee_info_table eitwhere ait.emp_id = eit.id and ait.att_work_datatime in(select max(att_work_datatime)from attendance_info_tablewhere att_work_datatime is not nullgroup by Date(att_work_datatime))order by ait.att_work_datatime asc;
步骤和2.1中统计每天来的最早的人的方法相同,唯一不同的是对表中列中after_work_datatime的所有值进行升
序排序,并将查询的列由att_work_datatime改为after_work_datatime,sql语句如下:
from employee_info_table as em ,
(select id,att_work_datatime,after_work_datatime,emp_id
from attendance_info_table
where after_work_datatime is not null
order by after_work_datatime)
as tmp
where em.id=tmp.emp_id
group by Date(after_work_datatime)
select eit.*, ait.after_work_datatimefrom attendance_info_table ait, employee_info_table eitwhere ait.emp_id = eit.id and ait.after_work_datatime in(select min(after_work_datatime)from attendance_info_tablewhere after_work_datatime is not nullgroup by Date(after_work_datatime))order by ait.after_work_datatime asc;
from employee_info_table as em ,
(select id,att_work_datatime,after_work_datatime,emp_id
from attendance_info_table
where after_work_datatime is not null
order by after_work_datatime desc)
as tmp
where em.id=tmp.emp_id
group by Date(after_work_datatime)
select eit.*, ait.after_work_datatimefrom attendance_info_table ait, employee_info_table eitwhere ait.emp_id = eit.id and ait.after_work_datatime in(select max(after_work_datatime)from attendance_info_tablewhere after_work_datatime is not nullgroup by Date(after_work_datatime))order by ait.after_work_datatime asc;
from
(select
id,att_work_datatime,after_work_datatime,timediff(after_work_datatime,att_work_datatime)
as att_time,emp_id
select eit.*,tmp.att_time, tmp.att_work_datatimefrom employee_info_table eit,(select id,att_work_datatime,timediff(after_work_datatime,att_work_datatime) as att_time,emp_idfrom attendance_info_tablewhere att_work_datatime is not null and after_work_datatime is not null) as tmpwhere eit.id=tmp.emp_id and tmp.att_time in(select max(timediff(after_work_datatime,att_work_datatime)) as att_timefrom attendance_info_tablewhere att_work_datatime is not null and after_work_datatime is not nullgroup by date(att_work_datatime))group by date(tmp.att_work_datatime)order by att_work_datatime;执行出的结果如下图所示:
select eit.*,tmp.att_time, tmp.att_work_datatimefrom employee_info_table eit,(select id,att_work_datatime,timediff(after_work_datatime,att_work_datatime) as att_time,emp_idfrom attendance_info_tablewhere att_work_datatime is not null and after_work_datatime is not null) as tmpwhere eit.id=tmp.emp_id and tmp.att_time in(select min(timediff(after_work_datatime,att_work_datatime)) as att_timefrom attendance_info_tablewhere att_work_datatime is not null and after_work_datatime is not nullgroup by date(att_work_datatime))group by date(tmp.att_work_datatime)order by att_work_datatime;执行结果如下所示:
select date(att_work_datatime) as date,count(*) as late_numsfrom attendance_info_tablewhere timediff(time(att_work_datatime),'09:30:59') > 0 and att_work_datatime is not nullgroup by date(att_work_datatime)
select date(after_work_datatime) as date,count(*) as leave_early_numsfrom attendance_info_tablewhere after_work_datatime is not nulland timediff(time(after_work_datatime),'18:00:00')<0or timediff(after_work_datatime,att_work_datatime)<'08:00:00'group by date(after_work_datatime)执行结果如下图所示:
select eit.*, count(*) as late_numsfrom attendance_info_table as ait,employee_info_table as eitwhere ait.att_work_datatime is not nulland timediff(time(ait.att_work_datatime),'09:30:59') > 0and ait.emp_id = eit.idgroup by emp_idorder by late_nums desc;

select eit.*,timediff(time(ait.att_work_datatime),'09:30:59') as lately_times,date(ait.att_work_datatime) as lately_datefrom attendance_info_table as ait,employee_info_table as eitwhere ait.att_work_datatime is not nulland timediff(time(ait.att_work_datatime),'09:30:59') > 0and eit.id=ait.emp_idorder by eit.emp_name asc;执行结果如下:
select
eit.*,timediff(time(ait.att_work_datatime),'09:30:59') as
lately_times,date(ait.att_work_datatime) as
lately_date,(10+1*(TIME_TO_SEC(timediff(time(ait.att_work_datatime),'09:30:59')))/60)
as '罚金(元)'
from attendance_info_table as ait,employee_info_table as eit
where ait.att_work_datatime is not null
and timediff(time(ait.att_work_datatime),'09:30:59') > 0
and eit.id=ait.emp_id
order by eit.emp_name asc
执行结果如下:
6.1计算出公司每天因为迟到所扣的钱select tmp.lately_date,sum(tmp.fadefor) as '总罚金(元)'
from
(select eit.*,timediff(time(ait.att_work_datatime),'09:30:59') as
lately_times,date(ait.att_work_datatime) as
lately_date,(10+1*(TIME_TO_SEC(timediff(time(ait.att_work_datatime),'09:30:59')))/60)
as fadefor
from attendance_info_table as ait,employee_info_table as eit
where ait.att_work_datatime is not null
and timediff(time(ait.att_work_datatime),'09:30:59') > 0
and eit.id=ait.emp_id
order by eit.emp_name asc) as tmp
group by tmp.lately_date执行结果如下:
select tmp.id,tmp.emp_name,sum(tmp.fadefor) as 'total_fadefor' from
(select eit.*,(10+1*(TIME_TO_SEC(timediff(time(ait.att_work_datatime),'09:30:59')))/60) as 'fadefor'
from attendance_info_table as ait,employee_info_table as eit
where ait.att_work_datatime is not null
and timediff(time(ait.att_work_datatime),'09:30:59') > 0
and eit.id=ait.emp_id) as tmp
group by tmp.id
order by total_fadefor desc;


(select eit.*,count(*) as normal_nums
from attendance_info_table as ait,employee_info_table as eit
where ait.att_work_datatime is not null
and ait.after_work_datatime is not null
and timediff(time(ait.att_work_datatime),'09:30:59') < 0
and timediff(after_work_datatime,att_work_datatime)>'08:00:00'
and ait.emp_id = eit.id
group by ait.emp_id
)as tmp where tmp.normal_nums>=21

(select eit.*,count(*) as normal_nums
from attendance_info_table as ait,employee_info_table as eit
where ait.att_work_datatime is not null
and ait.after_work_datatime is not null
and timediff(time(ait.att_work_datatime),'09:30:59') < 0
and timediff(after_work_datatime,att_work_datatime)>'08:00:00'
and ait.emp_id = eit.id
group by ait.emp_id
)as tmp
where tmp.normal_nums>=
(select count(*)
from
(select date(att_work_datatime) as date
from attendance_info_table
where att_work_datatime is not null
group by date(att_work_datatime)) as tmp)
一个关于考勤统计的sql研究的更多相关文章
- mysql统计类似SQL语句查询次数
mysql统计类似SQL语句查询次数 vc-mysql-sniffer 工具抓取的sql分析. 1.先用shell脚本把所有enter符号替换为null,再根据语句前后的字符分隔语句 grep -Ev ...
- 考勤输入导入OA平台与考勤统计报表导出功能源代码
注:以某某公司为例,每日签到时间为8点整 每日签退时间为17点30分 规则:公司签到签退时间在OA平台中可以视实际情况调整,当天有请假并通过工作流审批通过为有效,当天因公外出并通过工作流审批通过为 ...
- c#考勤统计
现在项目需求,需要从多张表中获取数据,组装到一个实体对象中,并通过计算统计出每个员工的考勤记录.(全凭自己思考做的,不足的地方希望各位大神指正!毕竟自己能力有限,思考不全) 考勤统计列表: 明细列表: ...
- 如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;)。
1.如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;). 2.select查询的多个字段之间要用逗号“,”分割,如果查询涉及多个表,那多个表之 ...
- --投资情况统计详情sql
--投资情况统计详情sqlselect BidRecord.*, RegInfo.UserName,UserInfo.phone,BorrowInfo.Title,BorrowInfo.BorrowC ...
- 写一个程序,统计自己C语言共写了多少行代码,Github基本操作
前言 在上一篇博客中,本人提到了自己的文件操作可以说是几乎没用过.现在想想,这也算是只在OJ上做题的一个弊端吧.虽然通过OJ做题是一个学习代码好手段,但其他方面也要多多涉猎才好,而不是说OJ用不到文件 ...
- 已知一个字符串S 以及长度为n的字符数组a,编写一个函数,统计a中每个字符在字符串中的出现次数
import java.util.Scanner; /** * @author:(LiberHome) * @date:Created in 2019/3/6 21:04 * @description ...
- 如何用java完成一个中文词频统计程序
要想完成一个中文词频统计功能,首先必须使用一个中文分词器,这里使用的是中科院的.下载地址是http://ictclas.nlpir.org/downloads,由于本人电脑系统是win32位的,因此下 ...
- 核心API的使用(给定一个字符串,统计每个字符出现的次数)
/** * 给定一个字符串,统计每个字符出现的次数. 如:abdaewrwqask435a1aasd */public class ReplaceString { static int length; ...
随机推荐
- AngularJS中的DOM value与view value
在看AngularJS的文档的时候经常会见到三个名词:DOM value.view value和model value. model value是模型值,view value是视图值,可这个DOM v ...
- DIY微型操作系统(1)—— 开发的准备
这个连载是根据<30天自制操作系统>这本书所写 只是类似于补充之类的东西,要详细的讲解,还请参照书上的内容 所以,首先我们要感谢作者川合秀实先生!(鞠躬) 为什么我想写这么一个补充的? 因 ...
- 这是一个专注于电脑技术、软件应用、互联网、嵌入式,电子技术行业等的原创IT博客
http://www.choovin.com/ 这是一个专注于电脑技术.软件应用.互联网.嵌入式,电子技术行业等的原创IT博客
- 切换python版本
安装python3.6.5后, alias python='/usr/bin/python3.6'
- 内网dns劫持
进行内网的dns劫持呢 ---> 我们需要用到ettercap 和ettercap内置的工具dns_spoof 1.我们需要开启ip转发 echo >/proc/sys/net/ipv4/ ...
- SWIFT中函数返回值为Tuple
在playgroundm内键入以下代码,求一个成绩数组内最大分值和最小分值 func maxminScore(scores:Array<Int>) -> (maxScore:Int, ...
- proxool配置及测试(数据库用的MySQL)
Proxool连接池设置 Proxool连接池是sourceforge下的一个开源项目,这个项目提供一个健壮.易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况. ...
- Linux文件共享(单进程之间、多进程之间)
转载:https://www.cnblogs.com/frank-yxs/p/5925603.html 在同一个进程中,实现文件共享的方法有两种: 多次使用open函数打开相同文件 使用dup/dup ...
- 浏览器中的data类型的Url格式,data:image/png,data:image/jpeg!(源自:http://blog.csdn.net/roadmore/article/details/38498719)
所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些“小”的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag,哪怕这个图片非常非常 ...
- MySQL Disk--磁盘相关参数
/sys/block/sda/queue/nr_requests 磁盘队列长度.默认只有 128 个队列,可以提高到 512 个.会更加占用内存,但能更加多的合并读写操作,速度变慢,但能读写更加多的量 ...


