You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:52:57