一个关于考勤统计的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; ...
随机推荐
- STL标准库-Tuple
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 在前面我介绍过一次tuple,今天在书上也看到了tuple,那就在写一次吧. tuple(元组),他的内部可以放任意类型的变量( ...
- L228 the complicated issue of equality: non-disabled actors play disabled roles
Bryan Cranston’s defence of playing a wheelchair user in the new comedy-drama The Upside has underli ...
- ionic 编写自定义控件
创建组件 在项目所在目录下执行: ionic g component <ComponentName> 在src/components中会出现: --components |--Compon ...
- L2-003. 月饼(贪心)
L2-003. 月饼 简单的结构体和排序应用题 #include<iostream> #include<stdio.h> #include<algorithm> u ...
- C语言基础总结 分类: iOS学习 c语言基础 2015-06-11 10:08 23人阅读 评论(0) 收藏
//欲练此功必先自宫!!! //第一天:C语言的基础 //进制 //2进制, 10进制, 8进制, 16进制 //注:8进制数前加0, 16进制数前加0x ...
- shell 脚本实战笔记(10)--spark集群脚本片段念念碎
前言: 通过对spark集群脚本的研读, 对一些重要的shell脚本技巧, 做下笔记. *). 取当前脚本的目录 sbin=`dirname "$0"` sbin=`cd &quo ...
- 查看camera设备-linux
前言 本文介绍如何在linux平台查看是否有camera外设. 操作过程 1.打开shell,输入以下命令: ls /dev/video* 即可查看是否有camera外设: 2.如果确实连接了came ...
- Spring MVC 学习)——控制器与@RequestMapping详解
Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解 一.控制器定义 控制器提供访问应用程序的行为,通常通过服务接口定义或注解定义两种方法实现. 控制器解析用户的请求 ...
- Codeforces Round #224 (Div. 2) A. Ksenia and Pan Scales
A. Ksenia and Pan Scales time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Java8 (Function,Consumer,Predicate,Supplier)详解
1. https://blog.csdn.net/lzm18064126848/article/details/70199769 1.1 https://blog.csdn.net/turbo_zon ...


