Как использовать запрос ms sql для определения максимального количества одновременных сеансов за промежуток времени - PullRequest
1 голос
/ 14 января 2020

Допустим, у меня есть простая таблица, например, такая:

Сеанс

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 сеанса одновременно и так далее. В этом случае запрос должен вернуть 3.

1 Ответ

1 голос
/ 14 января 2020

Для этого вам нужен подсчетный стол. Я создаю его здесь на лету, но желательно, чтобы он также создавался как обычная таблица.

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);

Возвращает

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 от <= до строгого < для получения ожидаемого результата.

...