请求编写MS SQL查询语句合并计算机登录时间范围
解决方案
要实现将用户的登录时间段合并为连续/接近的时间范围,我们可以使用MS SQL的窗口函数(LAG、SUM)来分组并聚合时间。以下是针对你的需求编写的查询语句:
WITH LoginGroups AS ( SELECT Usrkey, Username, DateTime_From, DateTime_To, -- 标记新分组:当前登录开始时间与上一次登录结束时间间隔超过2小时则开启新组 -- 你可以根据实际需求调整间隔阈值(这里是120分钟) CASE WHEN DATEDIFF(MINUTE, LAG(DateTime_To) OVER (PARTITION BY Usrkey, Username ORDER BY DateTime_From), DateTime_From) > 120 THEN 1 ELSE 0 END AS NewGroupFlag FROM Table1 ), GroupIDs AS ( SELECT Usrkey, Username, DateTime_From, DateTime_To, -- 累计计算分组ID,相同分组的ID一致 SUM(NewGroupFlag) OVER (PARTITION BY Usrkey, Username ORDER BY DateTime_From ROWS UNBOUNDED PRECEDING) AS GroupID FROM LoginGroups ) SELECT Usrkey, Username, MIN(DateTime_From) AS RangeFrom, MAX(DateTime_To) AS RangeTo FROM GroupIDs GROUP BY Usrkey, Username, GroupID ORDER BY Usrkey, RangeFrom;
说明
- 第一步(LoginGroups CTE):使用
LAG函数获取当前用户上一次登录的结束时间,计算当前登录开始时间与上一次结束时间的分钟间隔。如果间隔超过120分钟(2小时),标记为新分组。 - 第二步(GroupIDs CTE):通过累计求和
NewGroupFlag,为每个连续的登录时间段分配唯一的分组ID。 - 第三步(聚合查询):按用户和分组ID聚合,取分组内最早的开始时间和最晚的结束时间,得到合并后的时间范围。
匹配你的期望结果
针对你提供的Table2结果,需要注意:
- 对于用户
Fox,该查询会正确合并间隔小于2小时的登录记录,得到你期望的三个分组。 - 对于用户
Foxi的跨天记录(2012-01-01 12:50到2012-01-02 09:25),当前的2小时阈值会将其分为两个分组。如果需要强制合并跨天的记录,可以修改CASE条件,例如忽略日期差异:
但这个调整可能会影响其他分组逻辑,建议根据实际业务需求确认合并规则。CASE WHEN CAST(DateTime_From AS TIME) > CAST(LAG(DateTime_To) OVER (PARTITION BY Usrkey, Username ORDER BY DateTime_From) AS TIME) THEN 0 WHEN DATEDIFF(MINUTE, LAG(DateTime_To) OVER (PARTITION BY Usrkey, Username ORDER BY DateTime_From), DateTime_From) > 120 THEN 1 ELSE 0 END AS NewGroupFlag
内容的提问来源于stack exchange,提问作者Horia
相关产品推荐
相关产品推荐

