如何修正SQL查询以获取当日每位在岗员工最新打卡时间
修正SQL以获取当日在岗员工的最新打卡记录
嘿,我来帮你捋捋这个SQL的问题和修正方案~
首先先指出原SQL里的几个明显问题:
- JOIN条件里多了多余的逗号,而且关联逻辑写错了:
INNER JOIN personal AS a on zp.USER_ID, = zp.USER_ID,这里应该写成INNER JOIN personal AS a ON a.USER_ID = zp.USER_ID,不然这个关联不仅无效,还会直接报语法错误。 - 原查询如果同一个员工当日有多个未离岗的打卡记录(比如重复打卡),会返回多条数据,但你需要的是每位用户的最新Arrive时间,所以得用分组或者窗口函数来过滤出每个用户的最新记录。
接下来是修正后的SQL,这里用窗口函数ROW_NUMBER()来实现,它能帮我们给每个用户的记录按时间排序,只保留最新的那一条:
WITH RankedRecords AS ( SELECT zp.ID, zp.USER_ID, zp.Arrive, zp.Deppart, zp.DATUM, -- 按用户分组,按Arrive时间倒序排名,最新的记录排第1 ROW_NUMBER() OVER (PARTITION BY zp.USER_ID ORDER BY zp.Arrive DESC) AS RecordRank FROM time_recording AS zp -- 修正后的关联条件,关联personal表的用户ID INNER JOIN personal AS a ON a.USER_ID = zp.USER_ID WHERE zp.Arrive IS NOT NULL AND zp.Deppart IS NULL AND zp.DATUM = CONVERT(date, GETDATE()) ) SELECT ID, USER_ID, Arrive, Deppart, DATUM FROM RankedRecords WHERE RecordRank = 1 ORDER BY ID DESC;
如果你的数据库不支持CTE(比如老版本的SQL Server),也可以用子查询的方式:
SELECT ID, USER_ID, Arrive, Deppart, DATUM FROM ( SELECT zp.ID, zp.USER_ID, zp.Arrive, zp.Deppart, zp.DATUM, ROW_NUMBER() OVER (PARTITION BY zp.USER_ID ORDER BY zp.Arrive DESC) AS RecordRank FROM time_recording AS zp INNER JOIN personal AS a ON a.USER_ID = zp.USER_ID WHERE zp.Arrive IS NOT NULL AND zp.Deppart IS NULL AND zp.DATUM = CONVERT(date, GETDATE()) ) AS SubQuery WHERE RecordRank = 1 ORDER BY ID DESC;
额外补充说明下逻辑:
PARTITION BY zp.USER_ID表示按用户ID分组,每个用户的记录单独排序ORDER BY zp.Arrive DESC让每个用户的记录按Arrive时间从新到旧排,最新的那条排名为1- 最后过滤
RecordRank = 1就得到了每个用户当日最新的未离岗打卡记录
内容的提问来源于stack exchange,提问作者lasta
相关产品推荐
相关产品推荐

