0

ホテルの無料の部屋を開始日と終了日で表示しようとしています

ここに画像の説明を入力してください

このコードを使用すると、予約済みの部屋のみが表示されますが、予約されていない部屋は表示されません。

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

選択した日付に予約されている部屋を含まないすべての部屋を取得するには、何を変更する必要がありますか?

4

2 に答える 2

2

変数名と列名でのデータではなく日付の使用を許してください。

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 ) ) ) )
于 2012-05-15T22:33:58.737 に答える
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 )

いくつかの良いコメント。左の結合で「未使用の部屋」が得られることはわかっています。

キャンセルフィールドがない場合、以下が機能するはずです。

set @checkindate = '2012-05-15';

set @checkoutdate = '2012-05-17';

予約からroom_idを選択します(Data_Check_inとData_Check_outの間の@checkindateまたはData_Check_inとData_Check_outの間の@checkoutdate)

しかし、キャンセルすると、必要なすべての日が利用可能であることを知る必要があるため、事態はさらに困難になります。これは、個々の日のセット操作が必要なように感じます。

于 2012-05-15T19:08:58.913 に答える