SQL 服务器 - 计数会话 - 间隙和孤岛
SQL Server - Counting Sessions - Gaps and islands
如果我们在 SQL 服务器中有一个 table 具有以下数据:
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 开始,对于每个日志 activity,如果时差超过一个小时,则将会话数增加 1。
这是一个相当大的 table,具有不同的用户 ID。我已经尝试将游标组合用于循环不同的用户和 WHILE LOOPS 以通过逐行迭代会话计数来增加。它需要很长时间才能完成,当 table 变大时,这甚至可能不是正确的方法。必须有更好的方法来做到这一点。有什么指点吗?
我需要的结果集是这样的:
ID SessionCount
1110 28
1145 42
1116 38
也许是这样的:
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(或第一行为空),则将其计算为总和中的 1,否则计算为零。
您可以使用“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 服务器中有一个 table 具有以下数据:
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 开始,对于每个日志 activity,如果时差超过一个小时,则将会话数增加 1。
这是一个相当大的 table,具有不同的用户 ID。我已经尝试将游标组合用于循环不同的用户和 WHILE LOOPS 以通过逐行迭代会话计数来增加。它需要很长时间才能完成,当 table 变大时,这甚至可能不是正确的方法。必须有更好的方法来做到这一点。有什么指点吗?
我需要的结果集是这样的:
ID SessionCount
1110 28
1145 42
1116 38
也许是这样的:
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(或第一行为空),则将其计算为总和中的 1,否则计算为零。
您可以使用“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