简体   繁体   中英

mysql query for getting all rooms which are not booked between a date range not giving expected results

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!

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.

Demo here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM