在这里,我们要做一个简单的员工考勤记录查询系统的后台数据库。业务需求如下所示:
解决这个问题的时候本来考虑的是在考勤信息记录表中按照日期对考勤信息进行分组,然后取每组中上班时间(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)