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.
精彩评论