左连接不起作用

时间:2012-05-15 18:56:24

标签: sql-server

我想通过开始日期和结束日期显示我酒店的免费房间

enter image description here

当我使用此代码时,它只向我显示预订中出现的房间,但它没有显示我从未预订过的房间。

SELECT room.RoomID,room.Room_Type_ID,room.Room_number,room.NumberofSpots,
 res.Data_Check_in,res.Data_Check_out FROM    

      dbo.Reservation res JOIN dbo.Room room ON room.RoomID=res.Room_ID
      WHERE NOT(res.Data_Check_in<=@p_StartData AND res.Data_Check_out>=@p_EndData)

当我使用此代码时,它会显示所有房间,甚至是那些保留的房间:

SELECT DISTINCT r.*
FROM dbo.Room r LEFT JOIN dbo.Reservation  res ON r.RoomID=res.Room_ID
AND  NOT(res.Data_Check_in<='2012-05-07' AND res.Data_Check_out>='2012-06-13')
AND res.Cancel=0

如果没有为所选日期保留的房间,我应该修改哪些房间?

2 个答案:

答案 0 :(得分:2)

请原谅在变量和列名中使用Date而不是Data。

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 ) ) ) )

答案 1 :(得分:0)

怎么样

SELECT Dr.* FROM dbo.Room r LEFT JOIN dbo.Reservation res 
ON r.RoomID=res.Room_ID
WHERE res.Room_ID IS NULL

对于从未预订的房间。

左连接对预留的房间没有帮助,但今天没有。为此你需要像

这样的东西
SELECT Room_ID FROM Reservation WHERE Data_Check_out<=? OR Data_Check_in>=?
OR (Data_Check_out<=? AND Data_Check_in<=? AND Cancel=1 )

一些好的评论。我们知道左连接会给我们“从未使用过的房间”。

如果没有取消字段,以下内容应该有效:

  

设置@checkindate ='2012-05-15';

     

设置@checkoutdate ='2012-05-17';

     

从预订处选择room_id(@checkindate之间)   Data_Check_in和Data_Check_out或@checkoutdate之间   Data_Check_in和Data_Check_out)

但取消会让事情变得更加困难,因为我们需要知道所有想要的日子都可用。这种感觉更像是个人日子的固定操作。