获取您想要的结果集有两部分。
- 将具有相同“状态”值的所有连续日期合并在一起
返回一个组合结果集,具有:
- 完全落在您的日期从/到参数内的所有范围
- 与您的从/到参数开头部分重叠的计算范围
- 与您的从/到参数结尾部分部分重叠的计算范围
对于日期合并,您可以查看这两个链接以了解合并连续日期范围的方法:
http://www.sqlservercentral.com/Forums/Topic1364849-392-1.aspx
http://sqlmag.com/blog/solutions-packing-date-and-time-intervals-puzzle
我使用了那里最易读的一个示例。但是,如果你正在寻找更高效的查询,可以查看其他示例。
以下是一个返回你示例中结果集的示例查询:
合并具有相同状态的连续日期行
with all_times (time_type,date_range_part,status) as (
select 'start',
starttime,
status
from table_status
union all
select 'end',
endtime,
status
from table_status),
ordered_starts as (
select date_range_part,
status,
row_number() over(partition by status order by date_range_part, time_type desc) as rnboth,
2*(row_number() over(partition by status,time_type order by date_range_part))-1 as rnstartend
from all_times),
ordered_ends as (
select date_range_part,
status,
row_number() over(partition by status order by date_range_part desc,time_type) as rnbothrev,
2*(row_number() over(partition by status,time_type order by date_range_part desc))-1 as rnstartendrev
from all_times),
starts as (
select date_range_part,
status,
row_number() over(partition by status order by date_range_part) as rn
from ordered_starts
where rnboth=rnstartend),
ends as (
select date_range_part,
status,
row_number() over(partition by status order by date_range_part) as rn
from ordered_ends
where rnbothrev=rnstartendrev)
select
s.status,
s.date_range_part [start_time],
e.date_range_part [end_time]
into #table_status_merged
from starts s
inner join ends e on e.status=s.status and e.rn=s.rn and s.date_range_part<=e.date_range_part
order by s.date_range_part;
返回一个结果集,其中所有范围都完全在您的日期参数内,包括一个计算出的起始范围和一个计算出的结束范围。
declare @from datetime
declare @to datetime
set @from = '2007-10-17 00:00:00.000'
set @to = '2007-10-17 23:59:59.000'
select
[status],
@from,
end_time
from #table_status_merged
where start_time < @from
and end_time <= @to
union all
select
[status],
start_time,
end_time
from #table_status_merged
where start_time >= @from
and end_time <= @to
union all
select
[status],
start_time,
@to
from #table_status_merged
where start_time >= @from
and end_time > @to
drop table #table_status_merged