在sql中使用“Not In”语句获取重复的键

时间:2011-05-09 16:45:55

标签: sql sql-server

我的问题是:

有一个sql存储过程,它为我提供了一个给定hotelidbookinbookout日期的hotel_reservation表中两个日期之间的免费房间列表。

以下是程序:

    ALTER PROCEDURE dbo.StoredProcedure1
    (
    @DateStart date,
    @DateEnd date,
    @hotel_id int
    )

AS
    SELECT DISTINCT room_type_id, room_id
    FROM Room
WHERE room_id NOT IN (
        SELECT room_id
        FROM Hotel_Reservation
        WHERE @DateStart BETWEEN bookingStart AND bookingEnd
    OR @DateEnd BETWEEN bookingStart AND bookingEnd
    or bookingStart BETWEEN @DateStart AND @DateEnd  
    or bookingEnd BETWEEN @DateStart AND @DateEnd
    and hotel_id = @hotel_id 
) and hotel_id = @hotel_id 
    RETURN

Room表的定义:

room_id          int
hotel_id         int
room_type_id     varchar
price            money
room_description varchar

在房间表中,我使用了room_idHotel_id的重复密钥,因为ID为201的酒店可以有room_id 101也可以{id} 202的酒店{101}避免从重复的列我用过它。

room_id

的定义
hotel_reservation table

问题是:

当我运行此程序时如果用户在201酒店预订了房间号为101的房间,则另一位用户无法在酒店看到ID为202的房间,其房间为202.它会从酒店预订所有101个房间。

如何改进我的程序来克服这个问题?

感谢您的观看..

Image1Image2

2 个答案:

答案 0 :(得分:3)

更改为允许多个条件的NOT EXSTS?

在这种情况下,它可以检查两个酒店房间ID。

SELECT DISTINCT room_type_id, room_id
FROM Room R
WHERE NOT EXISTS (
        SELECT *
        FROM Hotel_Reservation H
        WHERE
    (
    @DateStart BETWEEN H.bookingStart AND H.bookingEnd
    OR @DateEnd BETWEEN H.bookingStart AND H.bookingEnd
    or H.bookingStart BETWEEN @DateStart AND @DateEnd  
    or H.bookingEnd BETWEEN @DateStart AND @DateEnd
    )
    and  --here is where we check **that room for that hotel**
    H.hotel_id = R.hotel_id and H.room_id = R.room_id
) 
and 
R.hotel_id = @hotel_id

编辑:

感谢Andriy M用一些括号

来纠正我的AND / OR运算符优先级

答案 1 :(得分:0)

这是一个可能的解决方案的快速运行。 (抱歉,我没时间测试它......)

    ALTER PROCEDURE dbo.StoredProcedure1 (    
     @DateStart date,    
     @DateEnd date,    
     @hotel_id int    
)
AS    

;WITH BookedRooms ( roomID )
AS (
    SELECT room_id        
    FROM Hotel_Reservation        
    WHERE hotel_id = @hotel_id
      AND ( @DateStart BETWEEN bookingStart AND bookingEnd    
         or @DateEnd BETWEEN bookingStart AND bookingEnd )
    )
SELECT DISTINCT room_type_id, room_id    
FROM Room
WHERE room_id NOT IN (
    SELECT room_id        
    FROM BookedRooms 
    ) 
and hotel_id = @hotel_id     

RETURN