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

Posted

技术标签:

【中文标题】SQL Server - 计算会话数 - 差距和孤岛【英文标题】:SQL Server - Counting Sessions - Gaps and islands 【发布时间】:2016-11-16 18:41:47 【问题描述】:

如果我们在 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

【问题讨论】:

【参考方案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,否则为 0。

【讨论】:

【参考方案2】:

您可以使用“LEAD”和“DATEDIFF”来实现。您可以通过LEAD 找到下一个“LogTime”值。

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

【讨论】:

以上是关于SQL Server - 计算会话数 - 差距和孤岛的主要内容,如果未能解决你的问题,请参考以下文章

如何查看SQL SERVER数据库当前连接数

SQL Server:寻找就业差距——孤岛和差距问题

Windows Server 2008 R2修改远程桌面连接数

SQL Server 的锁定和阻塞

windows server 2008远程桌面最大连接数设置

在 SQL Server 中计算员工一个月的休假数