Reputation: 1273
I'm creating a booking system and it has 2 tables
rooms
id | name | no_of_rooms
1 | Lake View | 4
2 | Royale | 2
3 | Sky View | 6
bookings
id |room_id | start | end | total_rooms
4 |1 | 2015-08-13 | 2015-08-14 | 2
5 |2 | 2015-08-20 | 2015-08-22 | 1
6 |2 | 2015-08-01 | 2015-08-13 | 1
and when creating a new booking on the search page I want to find the available rooms that is available within this date range
SEARCH VALUES start : 2015-08-11 end : 2015-08-12
Expected Result
id | name | no_of_rooms | available_rooms
1 | Lake View | 4 | 4
2 | Royale | 2 | 1
3 | Sky View | 6 | 6
Result I got
id | name | no_of_rooms | available_rooms
1 | Lake View | 4 | 0
2 | Royale | 2 | 1
3 | Skyview | 6 | 0
Here's the code I wrote for room availability
SELECT
r.id,
r.name,
r.no_of_rooms,
IFNULL(sum(b.total_rooms),0) as available_rooms
FROM rooms r
LEFT JOIN bookings b ON r.id = b.room_id AND
(
(b.start <= "2015-08-11" AND b.end >= "2015-08-11")
OR
(b.start <= "2015-08-12" AND b.end >= "2015-08-12")
)
GROUP BY r.id
I also don't want the to show unavailable rooms.No matter what I tried the results are completely wrong.Hope you guys can help me out!
Upvotes: 2
Views: 1544
Reputation: 72175
You can try:
SELECT r.id AS roomID, r.name, r.no_of_rooms,
r.no_of_rooms - COALESCE(t.bookedRooms,0) AS available_rooms
FROM rooms AS r
LEFT JOIN (
SELECT room_id, SUM(total_rooms) AS bookedRooms
FROM bookings
WHERE `start` < '2015-08-14' AND `end` > '2015-08-11'
GROUP BY room_id ) AS t
ON r.id = t.room_id
WHERE r.no_of_rooms - COALESCE(t.bookedRooms,0) > 0
The key to finding booked rooms for the specified period is the following predicate:
`start` <= '2015-08-12' AND `end` >= '2015-08-11'
The above gets all rooms whose booking period overlaps, even for one day, with the specified period.
Using a GROUP BY
on room_id
we can get the total sum of booked rooms per room_id
for the period specified.
To get the expected result set, we can just do a LEFT JOIN
with the derived table of booked aggregates and simply subtract the sum of booked rooms from the number of available rooms.
Upvotes: 4