人员考勤,MySQL数据库一个表自动生成3表筛选人员迟到早退缺勤
前言:漂亮的人事小姐姐找我帮忙弄考勤:由于人员考勤和门禁一起,打卡记录太多,打卡机只能导出一个打卡Excel总表,不容易人工筛选。
Excel表的格式是这样的:(这里101代替真实人名)
实现目标:
8:30上班,5:30下班,可以导出工作日来公司人员迟到早退和没来公司人员的缺勤情况表,这两个结果表。
也可以导出每人每天最早打卡最晚打卡记录表。
这个表需要导入MySQL数据库进行筛选。迟到早退好判断,其实这里最难判断的是全天缺勤,因为打卡机没有任何记录。
需要自动生成人员表(把不打卡人去掉),上班日期表(把非工作日去掉),打卡表(每人每天最早最晚打卡)3个表联查的。
1.先把Excel表格转下格式(分列)
转完后格式这样了
2.把表格导入MySQL数据库
3.因为人员在变动,每回给的打卡表人员不会一模一样,需要自动生成人员表(把不打卡人去掉),上班日期表(把非工作日去掉),打卡表(每人每天最早最晚打卡)3个表联查的。-- -- 删除不用打卡记录人员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | -- -- 删除不用打卡记录人员 DELETE FROM `考勤明细` WHERE `姓名` IN ( 'boss' , '张总' , '钟总' , '吴总' ); -- -- --创建上班日期表动态:超过一半人打卡加班算工作日:80是全体人员每天打卡次数,超过80代表上班日期,正常一天打卡110左右,周末单独来公司开门打卡的人不会超过80次打卡 DROP TABLE if exists d; CREATE TABLE d (SELECT `日期时间` FROM `考勤明细` WHERE (f5 < '08:30:00' ) OR (f5 > '17:30:00' ) GROUP BY `日期时间` HAVING COUNT(`姓名`) > 80); -- SELECT * FROM d; -- -- -- 创建人员临时表格 DROP TABLE if exists u; CREATE TABLE u (SELECT `姓名` FROM `考勤明细` GROUP BY `姓名`); -- SELECT * FROM u; -- -- -- 创建考勤明细表 DROP TABLE if exists k; CREATE TABLE k (SELECT * ,min(`f5`) as "最早打卡" , max(`f5`) as "最晚打卡" FROM `考勤明细` GROUP BY `姓名`,`日期时间` ORDER BY `日期时间`,`姓名`); -- SELECT * FROM k ORDER BY `姓名`,`日期时间`; -- 早上没打卡-- -- 晚上没打卡,这应该链接上班日期d表 SELECT `姓名`,`日期时间`,`f4` as '星期' ,`最早打卡`,`最晚打卡`, '迟到' FROM k WHERE `最早打卡` > '08:30:00' AND f4 != '星期日' AND f4 != '星期六' UNION SELECT `姓名`,`日期时间`,`f4` as '星期' ,`最早打卡`,`最晚打卡`, '早退' FROM k WHERE `最晚打卡` < '17:30:00' AND f4 != '星期日' AND f4 != '星期六' ORDER BY `姓名`,`日期时间`;<br><br>第2种写法:<br>(SELECT k.`姓名`,k.`日期时间`,k.`f4` as '星期' ,k.`最早打卡`,k.`最晚打卡`, '迟到' FROM k RIGHT JOIN d on k.`日期时间` = d.`日期时间` WHERE k.`最早打卡` > '08:30:00' )<br> UNION <br>(SELECT k.`姓名`,k.`日期时间`,k.`f4` as '星期' ,k.`最早打卡`,k.`最晚打卡`, '早退' FROM k RIGHT JOIN d on k.`日期时间` = d.`日期时间` WHERE `最晚打卡` < '17:30:00' ) <br>ORDER BY `姓名`,`日期时间`;<br><br> -- -- 早上也没打卡,晚上也没打卡,但是来了(这个不用了,上面能查出来) -- SELECT * FROM t2 WHERE `最早打卡` > '08:30:00' AND `最晚打卡` < '17:30:00' AND f4 != '星期日' AND f4 != '星期六' GROUP BY `姓名`,`日期时间` -- -- SELECT k.*, '全天缺勤' from d INNER join u on 1=1 LEFT join k on u.`姓名`= k.`姓名` order by d.`日期时间`,k.`姓名`; -- select b.*, '全天缺勤' from k a right join ( select * from u b,( select distinct `日期时间` from d) c) b on a.`姓名`=b.`姓名` and a.`日期时间`=b.`日期时间` WHERE a.`姓名` IS NULL -- |
结果如下
好了,可以给小姐姐了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)