更新以删除所有联合。
declare @tbl table (
idx int identity(1,1) primary key,
startdate datetime,
enddate datetime);
insert into @tbl (startdate, enddate)
select '2009-01-01', '2009-01-05'
union all select '2009-01-02', '2009-01-04'
union all select '2009-01-01', '2009-01-03'
union all select '2009-01-03', '2009-01-06'
union all select '2009-01-04', '2009-01-07'
union all select '2009-01-05', '2009-01-08'
select idx, startdate
, (select sum(in_or_out)
from (
select case when startdate<=all_events.startdate then 1 else 0 end
+ case when enddate <= all_events.startdate then -1 else 0 end as in_or_out
from @tbl
where startdate <= all_events.startdate
or enddate <= all_events.startdate) as previous
) as concurent
from @tbl all_events
order by startdate
这提供了开始会话的时间轴,同时列出了新会话开始时的并发会话计数:
idx startdate concurent
3 2009-01-01 00:00:00.000 2
1 2009-01-01 00:00:00.000 2
2 2009-01-02 00:00:00.000 3
4 2009-01-03 00:00:00.000 3
5 2009-01-04 00:00:00.000 3
6 2009-01-05 00:00:00.000 3
要获取原始请求(具有最大并发会话的一组会话),您需要运行此查询两次,一次以获取最大并发会话,一次以获取具有最大并发时间的会话的开始日期,然后必须获取这些会话。
更新:
好的,这是一个单一的查询,检索出最大并发会话。我更改了测试数据,以消除结束和开始的模糊重叠。
declare @tbl table (
idx int identity(1,1) primary key,
startdate datetime,
enddate datetime);
insert into @tbl (startdate, enddate)
select '2009-01-01', '2009-01-04 23:59:59'
union all select '2009-01-02', '2009-01-03 23:59:59'
union all select '2009-01-01', '2009-01-02 23:59:59'
union all select '2009-01-03', '2009-01-03 23:59:59'
union all select '2009-01-04', '2009-01-04 23:59:59'
union all select '2009-01-05', '2009-01-05 23:59:59'
select max_concurent_starts.startdate as concurentdate
, session.*
from (
select *
,(
select sum(in_or_out)
from (
select case when startdate<=all_events.startdate then 1 else 0 end
+ case when enddate <= all_events.startdate then -1 else 0 end
as in_or_out
from @tbl
where startdate <= all_events.startdate
or enddate <= all_events.startdate) as previous
) as concurent
from @tbl all_events) as max_concurent_starts
join @tbl as session
on session.startdate <= max_concurent_starts.startdate
and session.enddate >= max_concurent_starts.startdate
where concurent = (
select top 1 concurent
from (
select (
select sum(in_or_out)
from (
select case when startdate<=all_events.startdate then 1 else 0 end
+ case when enddate <= all_events.startdate then -1 else 0 end
as in_or_out
from @tbl
where startdate <= all_events.startdate
or enddate <= all_events.startdate) as previous
) as concurent
from @tbl all_events) as all_events_with_concurent
order by concurent desc)
order by concurentdate, startdate;
这会得到类似这样的结果:
concurentdate idx startdate enddate
2009-01-02 00:00:00.000 3 2009-01-01 00:00:00.000 2009-01-02 23:59:59.000
2009-01-02 00:00:00.000 1 2009-01-01 00:00:00.000 2009-01-04 23:59:59.000
2009-01-02 00:00:00.000 2 2009-01-02 00:00:00.000 2009-01-03 23:59:59.000
2009-01-03 00:00:00.000 1 2009-01-01 00:00:00.000 2009-01-04 23:59:59.000
2009-01-03 00:00:00.000 2 2009-01-02 00:00:00.000 2009-01-03 23:59:59.000
2009-01-03 00:00:00.000 4 2009-01-03 00:00:00.000 2009-01-03 23:59:59.000
以下是翻译:在
2009-01-02 00:00:00
这一天,有3个并发会话(3、1和2),它们各自有开始和结束时间。在
2009-01-03 00:00:00
也有3个并发会话(1、2和4),它们各自有开始和结束时间,存在平局。性能可能会有所不同。使用CTE在SQL 2005中可以将查询简化100万倍。