2

我在 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

更新:单个用户可以有多组登录/注销对,并且可能存在没有相应注销的登录。我想忽略没有相应值的登录或注销。

4

3 回答 3

6

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;
于 2012-08-03T14:58:12.467 回答
0

尝试

select datediff(s, min(InsertDate), max(InsertDate)) as diff
from your_table
group by UserId 
于 2012-08-03T14:52:19.047 回答
0

如果只有一次登录和退出;

select UserId, DATEDIFF(second,Min(InsertDate),Max(InsertDate)) as Duration, 
from Table1
Group By UserId
于 2012-08-03T14:53:58.423 回答