请原谅在变量和列名中使用日期而不是数据。
declare @p_StartDate as Date = '2012-05-07'
declare @p_EndDate as Date = '2012-06-13'
declare @Room as Table ( Room_ID Int Identity, Room_number VarChar(5) )
insert into @Room ( Room_number ) values
( '101' ), ( '102' ), ( '103' ), ( '104' ), ( '105' ),
( '201' ), ( '202' ), ( '203' ), ( '204' ), ( '205' )
declare @Reservation as Table ( ReservationID Int Identity, Room_ID Int, Date_Check_in Date, Date_Check_out Date, Cancel Bit )
insert into @Reservation ( Room_ID, Date_Check_in, Date_Check_out, Cancel ) values
( 3, '2012-05-01', '2012-05-06', 0 ), -- Before.
( 3, '2012-06-14', '2012-07-01', 0 ), -- After.
( 4, '2012-05-07', '2012-06-13', 0 ), -- Matching.
( 5, '2012-06-01', '2012-06-05', 0 ), -- Within.
( 6, '2012-05-01', '2012-06-01', 0 ), -- Overlapping start.
( 7, '2012-06-01', '2012-06-15', 0 ), -- Overlapping end.
( 8, '2012-06-01', '2012-06-05', 1 ), -- Within, but cancelled.
( 9, '2012-06-01', '2012-06-15', 1 ), -- Overlapping, but cancelled.
( 10, '2012-01-01', '2012-12-31', 0 ) -- Containing.
select room.Room_ID, room.Room_number
from @Room as room
where not exists (
select 42
from @Reservation
where Room_ID = room.Room_ID and Cancel = 0 and
-- The date ranges overlap.
( ( ( @p_StartDate <= Date_Check_in ) and ( Date_Check_in <= @p_EndDate ) or
( @p_StartDate <= Date_Check_out ) and ( Date_Check_out <= @p_EndDate ) ) or
-- The desired range is contained in the reserved range.
( ( Date_Check_in <= @p_StartDate ) and ( @p_EndDate <= Date_Check_out ) ) ) )