如何使用 ms sql 查询来确定时间跨度内的最大并发会话数

How to use ms sql query to determine max number of concurrent sessions over a timespan

假设我有一个像这样的简单 table

会话

id dtmStarted dtmEnded

在分钟级别,我想知道一段时间内的最大并发会话数

这样

id   dtmStarted           dtmEnded
1 - '2020-01-01 10:00' - '2020-01-01 10:05'
2 - '2020-01-01 10:00' - '2020-01-01 10:05'
3 - '2020-01-01 10:00' - '2020-01-01 10:05'
4 - '2020-01-01 10:06' - '2020-01-01 10:09'
5 - '2020-01-01 10:07' - '2020-01-01 10:08'
6 - '2020-01-01 10:10' - '2020-01-01 10:11'

所以在 10:10 和 10:11 之间只有 1 个会话。在 10:07 和 10:08 之间有 2 个并发会话。在 10:00 - 10:01 之间有 3 个并发会话等等。在这种情况下,查询应该 return 3.

你需要一个计数 table。我在这里即时创建它,但最好也可以将其实例化为常规 table。

declare @t table(
  id int,
  dtmStarted datetime,
  dtmEnded datetime
  );
insert @t values
(1, '2020-01-01 10:00', '2020-01-01 10:05'),
(2, '2020-01-01 10:00', '2020-01-01 10:05'),
(3, '2020-01-01 10:00', '2020-01-01 10:05'),
(4, '2020-01-01 10:06', '2020-01-01 10:09'),
(5, '2020-01-01 10:07', '2020-01-01 10:08'),
(6, '2020-01-01 10:10', '2020-01-01 10:11');

declare @s datetime = '2020-01-01 10:00';
declare @e datetime = '2020-01-01 11:00';

-- table of 1000 numbers starting 0
with t0(n) as (
 select n 
 from (
    values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
    ) t(n)
),nmbs as(
   select row_number() over(order by t1.n) - 1 n
   from t0 t1, t0 t2, t0 t3
)
select dateadd(minute, n, @s) start, count(id) cnt
from nmbs
left join @t on dtmStarted <= dateadd(minute, n+1, @s) and dateadd(minute, n, @s)<= dtmEnded
where dateadd(minute, n+1, @s) <= @e
group by dateadd(minute, n, @s)
order by dateadd(minute, n, @s);

Returns

2020-01-01 10:01:00.000 3
2020-01-01 10:02:00.000 3
2020-01-01 10:03:00.000 3
2020-01-01 10:04:00.000 3
2020-01-01 10:05:00.000 4
2020-01-01 10:06:00.000 2
2020-01-01 10:07:00.000 2
2020-01-01 10:08:00.000 2
2020-01-01 10:09:00.000 2
2020-01-01 10:10:00.000 1
2020-01-01 10:11:00.000 1
2020-01-01 10:12:00.000 0
2020-01-01 10:13:00.000 0
2020-01-01 10:14:00.000 0
2020-01-01 10:15:00.000 0
...
2020-01-01 10:59:00.000 0

您可能需要将两个或其中一个谓词 dtmStarted <= dateadd(minute, n+1, @s) and dateadd(minute, n, @s) <= dtmEnded<= 更改为严格 < 以获得预期结果。