There are two parts to getting the result set you are looking for.
, , :
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
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
where start_time < @from
and end_time <= @to
union all
select
[status],
start_time,
end_time
from
where start_time >= @from
and end_time <= @to
union all
select
[status],
start_time,
@to
from
where start_time >= @from
and end_time > @to
drop table