SQL Server - 计算会话 - 差距和孤岛

时间:2016-11-16 18:41:47

标签: sql sql-server tsql sql-server-2012 gaps-and-islands

如果我们在SQL Server中有一个包含以下数据的表:

ID      Log_Time
1110    2016-10-31 20:34:50.000
1110    2016-10-31 20:34:58.000
1110    2016-10-31 20:35:03.000
1110    2016-11-01 01:28:29.000
1110    2016-11-01 01:28:33.000
1110    2016-11-01 01:28:37.000
1110    2016-11-01 01:28:42.000
1110    2016-11-01 01:28:46.000
1110    2016-11-01 01:28:50.000
1110    2016-11-01 01:28:54.000
1110    2016-11-01 01:28:59.000
1110    2016-11-01 01:29:03.000

假设每个用户操作都生成一个log_time条目。业务计算会计数量,如此计费 - 从会话1开始,对于每个日志活动,如果时间差超过一小时,则将会话计数增加1。

这是一个包含不同用户ID的相当大的表。我已经尝试了用于循环不同用户的游标组合,以及通过逐行迭代迭代会话计数来增加WHILE LOOPS。这需要很长时间才能完成,当这个表变大时,这可能甚至不是正确的方法。必须有更好的方法来做到这一点。有什么指针吗?

我需要的结果集是:

ID     SessionCount
1110   28
1145   42
1116   38

2 个答案:

答案 0 :(得分:1)

也许是这样的:

select ID, sum(case when diff is NULL or diff > 60 then 1 else 0 end)
from (
  select
    ID,
    datediff(minute, lag(Log_Time) 
    over (partition by ID order by Log_Time), Log_time) as diff
  from
    #tmp
) X
group by ID

这将检查前一行的延迟,如果它超过60(或第一行为null),那么它计算为1为总和,否则为零。

答案 1 :(得分:0)

您可以使用" LEAD"和" DATEDIFF"。你找到了下一个" LogTime"价值LEAD

SELECT
    A.ID,
    COUNT(A.ID) AS SesionCount
FROM
(
    SELECT 
        T.ID,
        DATEDIFF(HOUR, T.Log_Time, LEAD(T.Log_Time) OVER (ORDER BY T.Log_Time)) AS LogDateDiff
    FROM 
        @Tbl T
) A
WHERE
    A.LogDateDiff >= 1
GROUP BY
    A.ID