在SQL Server中合并同一张表的不同行实现签到签出关联
SQL Server 实现签到签出记录合并方案
没问题,我来帮你搞定这个需求!核心思路是给同一用户的签到、签出记录分别按时间排序,然后通过序号把对应的签到和签出配对起来,具体实现如下:
实现代码
-- 先给签到、签出记录分别分组排序,生成配对用的行号 WITH CheckInRecords AS ( SELECT Id, UserId, IsCheckIn, DateTime AS InDateTime, Image AS InImage, AccountId, -- 按用户分组,签到时间倒序(最新的签到在前)分配行号 ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY DateTime DESC) AS RowNum FROM YourTableName -- 这里替换成你的实际表名 WHERE IsCheckIn = 1 ), CheckOutRecords AS ( SELECT IsCheckIn AS IsCheckOut, DateTime AS OutDateTime, Image AS OutImage, UserId, -- 和签到记录用相同的排序规则,保证配对准确 ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY DateTime DESC) AS RowNum FROM YourTableName WHERE IsCheckIn = 0 ) -- 关联两个分组后的结果,按用户ID和行号配对 SELECT ci.Id, ci.UserId, ci.IsCheckIn, ci.InDateTime, ci.InImage, ci.AccountId, co.IsCheckOut, co.OutDateTime, co.OutImage FROM CheckInRecords ci LEFT JOIN CheckOutRecords co ON ci.UserId = co.UserId AND ci.RowNum = co.RowNum ORDER BY ci.InDateTime DESC;
代码说明
- CTE分组排序:
CheckInRecords筛选所有签到(IsCheckIn=1)记录,按用户分组后给每条签到记录分配行号,排序规则用DateTime DESC是为了让最新的签到优先配对最新的签出;CheckOutRecords同理处理签出(IsCheckIn=0)记录,必须和签到用完全相同的排序规则,否则配对会出错。
- 关联配对:通过
UserId和RowNum关联两个结果集,这样同一用户的第N条签到就会和第N条签出合并成一行。 - 灵活调整:如果你的业务是签到时间早于签出时间,也可以把
ORDER BY DateTime DESC改成ASC,确保顺序匹配;如果确定每条签到都有对应的签出,可以把LEFT JOIN换成INNER JOIN。
内容的提问来源于stack exchange,提问作者Nandan Kyada
相关产品推荐
相关产品推荐

