SQL Server 2016考勤数据查询:每日用户记录及门牌号需求
解决方案:SQL Server 2016 每日用户考勤记录查询
核心需求实现
你之前的问题出在没有将日期字段加入分组条件,导致只按USERID聚合得到了用户的全局最早记录。要实现每个用户每日一条记录,需要同时按USERID和转换后的日期分组,再配合聚合函数取当日的时间(比如最早或最晚):
SELECT USERID, CAST(Time AS DATE) AS Date, MIN(Time) AS DailyFirstCheckIn -- 若需要最晚记录,替换为MAX(Time) FROM YourTable GROUP BY USERID, CAST(Time AS DATE) ORDER BY Date, USERID;
延伸需求:添加任意Door字段
你的原SQL报错是因为Door字段既不在GROUP BY中,也没有使用聚合函数(SQL Server严格遵循GROUP BY规则)。要添加当日任意门牌号,有两种简单实现方式:
方式1:用聚合函数直接获取(无需额外分组)
利用MIN()或MAX()取当日任意一个Door值,和核心需求的分组逻辑兼容:
SELECT USERID, CAST(Time AS DATE) AS Date, MIN(Time) AS DailyCheckInTime, -- 可选保留时间字段 MIN(Door) AS DailyDoor -- 用MAX(Door)也可,均为当日任意门牌号 FROM YourTable GROUP BY USERID, CAST(Time AS DATE) ORDER BY Date, USERID;
方式2:用窗口函数灵活选择(适合需要关联时间的场景)
如果需要取当日某条特定记录的Door(比如最早打卡对应的门),或随机取一条,用ROW_NUMBER()窗口函数更灵活:
WITH DailyCTE AS ( SELECT USERID, CAST(Time AS DATE) AS Date, Time, Door, -- 按用户+日期分区,排序规则决定取哪条:Time取最早,NEWID()随机取 ROW_NUMBER() OVER (PARTITION BY USERID, CAST(Time AS DATE) ORDER BY Time) AS RowNum FROM YourTable ) SELECT USERID, Date, Time, Door FROM DailyCTE WHERE RowNum = 1 ORDER BY Date, USERID;
如果需要随机获取当日任意Door,把ORDER BY Time改成ORDER BY NEWID()即可。
内容的提问来源于stack exchange,提问作者Stoney321
相关产品推荐
相关产品推荐

