我在 SQL Server 2012 中有一个表,可以像这样跟踪登录和注销时间:
UserId Type InsertDate
2134 1 20120803 06:32:02.230
2134 1 20120803 10:12:24.350
2134 2 20120803 10:29:21.550
2134 2 20120803 14:10:34.220
5915 1 20120802 14:57:57.453
5915 2 20120802 16:59:00.477
(类型1为登录,类型2为退出。)
我想查询此表 - 以显示每个登录/注销对的计算时间跨度(以秒为单位)的用户 ID 分组列表,因此我最终得到如下结果:
UserID Duration
2134 1017
5915 7263
更新:单个用户可以有多组登录/注销对,并且可能有一次登录而没有相应的注销。我想忽略没有相应值的登录或注销。
最佳答案
SQL Server 2012 现在不再需要自连接和聚合。此解决方案处理同一用户的多次登录。
DECLARE @t TABLE(UserID INT, [Type] TINYINT, InsertDate DATETIME);
INSERT @t VALUES
(2134,1,'20120803 10:12:24.350'),
(2134,2,'20120803 10:29:21.550'),
(2134,1,'20120803 11:22:24.350'),
(2134,2,'20120803 11:47:21.550'),
(5915,1,'20120802 14:57:57.453'),
(5915,2,'20120802 16:59:00.477');
;WITH x AS (
SELECT UserID, [Type], InsertDate, Prev = LAG(InsertDate, 1) OVER
(PARTITION BY UserID ORDER BY InsertDate) FROM @t
)
SELECT UserID, DATEDIFF(SECOND, Prev, InsertDate) FROM x WHERE [Type] = 2;
-- or if you want cumulative time per user even if there are multiple login events:
;WITH x AS (
SELECT UserID, [Type], InsertDate, Prev = LAG(InsertDate, 1) OVER
(PARTITION BY UserID ORDER BY InsertDate) FROM @t
)
SELECT UserID, SUM(DATEDIFF(SECOND, Prev, InsertDate))
FROM x WHERE [Type] = 2 GROUP BY UserID;
在以前的版本中,您可以使用更详细的:
;WITH x AS
(
SELECT UserID, [Type], InsertDate,
rn = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY InsertDate)
FROM @t
)
SELECT x.UserID, DATEDIFF(SECOND, x.InsertDate, y.InsertDate)
FROM x INNER JOIN x AS y
ON x.UserID = y.UserID
AND x.rn = y.rn - 1
WHERE x.Type = 1
AND y.Type = 2;
关于sql - 从同一列中的两行获取时间跨度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11797989/