Должен быть способ уникальной идентификации каждого бронирования.Я бы предложил добавить столбец идентификаторов в таблицу RoomBooking и решить проблему, как показано в коде ниже:
create table Room
(
id int identity(1, 1) primary key clustered,
capacity int not null
)
go
create table RoomBooking
(
id int identity(1, 1) primary key clustered,
room int constraint FK_RoomBooking_Room foreign key references Room(id),
start_time datetime,
end_time datetime,
capacity_taken int
)
go
insert Room(capacity)
select 100 union all
select 200
insert RoomBooking(room, start_time, end_time, capacity_taken)
select 1, '2012-02-29 10:00', '2012-02-29 12:00', 10 union all
select 1, '2012-02-29 11:00', '2012-02-29 15:00', 10 union all
select 1, '2012-02-29 14:00', '2012-02-29 16:00', 10 union all
select 2, '2012-02-29 14:00', '2012-02-29 16:00', 10 union all
select 2, '2012-02-29 14:00', '2012-02-29 16:00', 10 union all
select 2, '2012-02-29 14:00', '2012-02-29 16:00', 10 union all
select 2, '2012-02-29 13:00', '2012-02-29 15:00', 10 union all
select 2, '2012-02-29 15:00', '2012-02-29 17:00', 10 union all
select 2, '2012-02-29 17:00', '2012-02-29 19:00', 10 union all
select 1, '2012-02-29 14:00', '2012-02-29 16:00', 10
go
declare @roomid int = 1
declare @check_period_start datetime = '2012-02-29 13:00'
declare @check_period_end datetime = '2012-02-29 15:00'
select
r.id, r.capacity - maxtaken.max_capacity_taken as remaining_capacity
from
Room r
join
(
select
id, MAX(sum_capacity_taken) max_capacity_taken
from
(
select
r.id, SUM(rb2.capacity_taken) + min(rb1.capacity_taken) sum_capacity_taken
from
Room r
join RoomBooking rb1 on rb1.room = r.id
left join RoomBooking rb2
on rb1.room = rb2.room
and rb1.id <> rb2.id
and
(
(rb2.start_time <= rb1.start_time and rb2.end_time >= rb1.start_time)
or (rb2.start_time <= rb1.end_time and rb2.end_time >= rb1.end_time)
)
where
rb1.end_time >= @check_period_start
and rb1.start_time <= @check_period_end
and rb2.end_time >= @check_period_start
and rb2.start_time <= @check_period_end
group by
r.id, rb1.id
) sct
group by id
) maxtaken on maxtaken.id = r.id
where
r.id = @roomid