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

基于SQL实现CheckTime表用户每日签到签退时间统计

按用户和日期分组统计签到签退时间的SQL实现

先明确你的需求:基于CheckTime表,按用户名和日期分组,将每组里最早的CheckTime作为签到时间(check in),最晚的作为签退时间(check out)。

先回顾下你的表结构:

CREATE TABLE [dbo].[CheckTime] (
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [UserName] [nchar](10) NULL,
 [CheckTime] [datetime] NULL,
 [Checktype] [nvarchar](50) NULL,
 [CheckinLocation] [nvarchar](50) NULL,
 [lat] [float] NULL,
 [lng] [float] NULL,
 CONSTRAINT [PK_CheckTime] PRIMARY KEY CLUSTERED ([ID] ASC) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

基础版:仅获取签到签退时间

你可以使用GROUP BY结合日期函数提取日期部分,再用MIN()和MAX()聚合函数分别获取签到和签退时间:

SELECT
    [UserName],
    CONVERT(date, [CheckTime]) AS [CheckDate],
    MIN([CheckTime]) AS [CheckInTime],
    MAX([CheckTime]) AS [CheckOutTime]
FROM [dbo].[CheckTime]
WHERE [UserName] IS NOT NULL AND [CheckTime] IS NOT NULL -- 过滤无效数据
GROUP BY [UserName], CONVERT(date, [CheckTime])
ORDER BY [CheckDate] DESC, [UserName]

代码解释

  • CONVERT(date, [CheckTime]):把datetime类型的CheckTime转换为date类型,这样就能按自然日分组,忽略具体时分秒。
  • MIN([CheckTime]):取每组中最早的时间,也就是签到时间。
  • MAX([CheckTime]):取每组中最晚的时间,也就是签退时间。
  • WHERE子句:过滤掉用户名或时间为空的无效记录,避免分组出现异常结果。
  • ORDER BY:按日期倒序、用户名排序,方便查看最新的打卡记录。

进阶版:获取签到签退对应的地点和经纬度

如果需要同时拿到签到/签退对应的打卡地点、经纬度,单纯的聚合函数没法直接关联这些字段,这时候可以用窗口函数ROW_NUMBER()来实现:

WITH RankedChecks AS (
    SELECT
        [UserName],
        CONVERT(date, [CheckTime]) AS [CheckDate],
        [CheckTime],
        [CheckinLocation],
        [lat],
        [lng],
        -- 按用户和日期分组,时间升序排序,第一条就是签到记录
        ROW_NUMBER() OVER (PARTITION BY [UserName], CONVERT(date, [CheckTime]) ORDER BY [CheckTime] ASC) AS CheckInRank,
        -- 按用户和日期分组,时间降序排序,第一条就是签退记录
        ROW_NUMBER() OVER (PARTITION BY [UserName], CONVERT(date, [CheckTime]) ORDER BY [CheckTime] DESC) AS CheckOutRank
    FROM [dbo].[CheckTime]
    WHERE [UserName] IS NOT NULL AND [CheckTime] IS NOT NULL
)
SELECT
    rc1.[UserName],
    rc1.[CheckDate],
    rc1.[CheckTime] AS [CheckInTime],
    rc1.[CheckinLocation] AS [CheckInLocation],
    rc1.[lat] AS [CheckInLat],
    rc1.[lng] AS [CheckInLng],
    rc2.[CheckTime] AS [CheckOutTime],
    rc2.[CheckinLocation] AS [CheckOutLocation],
    rc2.[lat] AS [CheckOutLat],
    rc2.[lng] AS [CheckOutLng]
FROM RankedChecks rc1
JOIN RankedChecks rc2
    ON rc1.[UserName] = rc2.[UserName]
    AND rc1.[CheckDate] = rc2.[CheckDate]
    AND rc1.CheckInRank = 1
    AND rc2.CheckOutRank = 1
ORDER BY rc1.[CheckDate] DESC, rc1.[UserName]

这个版本能完整获取每个用户每天的签到、签退时间及对应的打卡地点、经纬度,适合需要完整打卡明细的业务场景。

内容的提问来源于stack exchange,提问作者emadadel2008

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:38:10