开发者

SQL Scheduling - Select All Rooms Available for Given Date Range

I'm using Microsoft's idea for storing resource and booking information. In short, resources, such as a hotel room, do not have date records and booking records have a BeginDate and EndDate.

I'm trying to retrieve room availability information using MS's queries but something tells me that MS's queries leave much to be desired. Here's the MS article I'm referring to: http://support.microsoft.com/kb/245074

How can I retrieve available rooms for a given date range? Here's my query that returns a simple list of bookings:

SELECT r.RoomID, b.BeginDate, b.EndDate
FROM tblRoom as r INNER JOIN tblBooking b ON r.RoomID = b.AssignedRoomID;

But I'm still baffled as to how I can get a list of available rooms for a given date range?

I am using Microsoft Access but I'd like to keep my queries DBMS agnostic, as much as possible. While this isn't really my question, if you feel that the data model I'm using is unsound, please say so, as I am willing to consider a better way of storing my data.

Edit1:

I failed to mention that I don't like MS's queries for two reasons. First of all, I'm really confused about the 3 different OR operators in the WHERE clause. Are those really necessary? Secondly, I don't like the idea of saving a query and using it as a table although I'm willing to do that if it gets the job done, which in this case I believe it does.

Edit2:

This is the solution I've landed on using the excellent answer given here. This is MS Access SQL dialect (forgive me):

SELECT * FROM tblRoom AS r  
WHERE RoomID NOT IN  
 (SELECT AssignedRoomID as RoomID From tblBooking  
  WHERE assignedroomid IS NOT NULL AND assignedroomid = r.roomid AND 
    (BeginDate < @BookingInquiryEndDate AND EndDate > @BookingInqui开发者_运维知识库ryBeginDate)  
 )


You want all the rooms which do not have a booking in that date range, i.e., If your sql engine does subqueries...

Select * From Rooms r 
where not exists 
     (Select * From Bookings 
      Where room = r.room
         And startBooking < @endRange
         And endBooking > @startRange)

HIK, to understand the need for the room = r.room clause try these two queries

Query One (with room = r.room clause)

       Select r.*,
       Case Where Exists
           (Select * From Bookings 
            Where room = r.room
                 And startBooking < @endRange
                 And endBooking > @startRange) 
        Then 'Y' Else 'N' End HasBooking
    From Rooms r 

Query Two(without room = r.room clause)

    Select r.*,
       Case Where Exists
           (Select * From Bookings 
            Where startBooking < @endRange
                 And endBooking > @startRange) 
        Then 'Y' Else 'N' End HasBooking
    From Rooms r 

Notice the first one returns different values in HasBooking for each row of the output, because the subquery is 'Correleated' with the outer query... it is run over and over agaio, once for each outer query results row.

The second one is the same value for all rows... It is only executed once, because nothing in it is dependant on which row of the outer query it is being generated for.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜