sql - 从同一列中的两行获取时间跨度

标签 sql sql-server tsql sql-server-2012

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

相关文章:

php - 在其他表的多行中选择符合条件的行

sql - T-SQL EXEC 和作用域

mysql - SQL 查询 - 查找所有条目均为非 Null 的行

mysql - 如果触发器中存在条件,如何在 MySQL 表中插入记录

sql - SQL 中 WHERE 子句的索引性能

sql - T-SQL 基于非详尽查找返回更正后的列

sql - 在 SELECT 中选择行作为列

MySQL 按主键排序

c# - 错误: String or binary data would be truncated. 表值参数的数据不符合参数的表类型

sql-server - 必须声明标量变量