基于MS SQL 2008 R2的考勤数据查询SQL语句及结果咨询
考勤SQL查询技术分析与优化建议
我来针对你这段基于MS SQL 2008 R2的考勤查询语句和结果,给你一些实用的技术分析和优化建议:
基础信息梳理
- 使用环境:MS SQL Server 2008 R2
- 涉及业务表:
CHECKINOUT(考勤打卡记录表)、USERINFO(员工基础信息表)
原查询语句
SELECT CHECKINOUT.USERID, USERINFO.USERID, CHECKINOUT.SENSORID, USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME FROM CHECKINOUT, USERINFO WHERE CHECKINOUT.USERID=USERINFO.USERID AND USERINFO.BADGENUMBER=63 AND CHECKTIME BETWEEN '2017-03-26' AND '2017-04-26'
查询结果整理(表格形式更清晰)
| CHECKINOUT.USERID | USERINFO.USERID | SENSORID | BADGENUMBER | CHECKTIME |
|---|---|---|---|---|
| 181 | 181 | 100 | 63 | 2017-04-01 11:02:19.000 |
| 181 | 181 | 100 | 63 | 2017-04-02 10:12:52.000 |
| 181 | 181 | 100 | 63 | 2017-04-03 10:32:43.000 |
| 181 | 181 | 1 | 63 | ... |
核心优化与问题排查建议
1. 语句语法规范与精度优化
原语句使用了旧式的逗号连接表语法,建议改用标准的INNER JOIN写法,可读性和维护性更强;同时可以优化几个细节:
SELECT ci.USERID, ci.SENSORID, ui.BADGENUMBER, ci.CHECKTIME FROM CHECKINOUT ci INNER JOIN USERINFO ui ON ci.USERID = ui.USERID WHERE ui.BADGENUMBER = 63 AND ci.CHECKTIME BETWEEN '2017-03-26' AND '2017-04-26 23:59:59.997'
优化点说明:
- 给表取短别名(
ci、ui),简化语句长度 - 去掉重复的
USERID字段(内连接后两张表的USERID必然相等,无需重复输出) - 修正时间范围:原语句的
'2017-04-26'会默认匹配到当天0点整的记录,加上23:59:59.997才能覆盖当天所有打卡时间(MS SQL的datetime类型精度为3.33毫秒,用.997可以避免遗漏)
2. 索引优化提升查询效率
如果你的考勤表数据量较大,建议创建以下索引避免全表扫描:
- 针对
USERINFO表的工号查询:CREATE NONCLUSTERED INDEX IX_USERINFO_BADGENUMBER ON USERINFO(BADGENUMBER) INCLUDE(USERID); - 针对
CHECKINOUT表的用户+时间范围查询:CREATE NONCLUSTERED INDEX IX_CHECKINOUT_USERID_CHECKTIME ON CHECKINOUT(USERID, CHECKTIME) INCLUDE(SENSORID);
3. 结果异常排查提示
- 结果中出现不同的
SENSORID(比如100和1),说明该员工在不同的考勤设备上打卡,属于正常业务场景;如果是异常设备打卡,可以结合设备信息表进一步核实。 - 如果存在打卡记录缺失的情况,可以检查:
- 时间范围是否覆盖完整(比如是否漏掉了当天的结束时间)
BADGENUMBER字段类型:如果是字符串类型,需要用单引号包裹值(ui.BADGENUMBER = '63')- 是否有未同步到
CHECKINOUT表的原始打卡数据
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

