Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to find available rooms in a certain hotel, however, I am not able to find my mistake in my SQL queries (below). I hope someone can help me find my mistake.

My Booking Entity looks like this

Java
@Entity
@Table(name = "bookings")
public class BookingEntity extends BaseEntity {

    @ManyToOne
    private UserEntity guest;

    @ManyToOne
    private AccommodationEntity property;

    @Column(columnDefinition = "DATE", nullable = false)
    private LocalDate checkIn;

    @Column(columnDefinition = "DATE", nullable = false)
    private LocalDate checkOut;

Booked Rooms entity

Java
@Entity
@Table(name = "booked_rooms")
public class BookedRoomsEntity extends BaseEntity {

    @ManyToOne
    private BookingEntity booking;

    @ManyToOne
    private RoomEntity room;

Room Entity
Java
@Entity
@Table(name = "rooms")
public class RoomEntity extends BaseEntity {

    @ManyToOne
    private AccommodationEntity accommodationEntity;
     private String roomType;


What I have tried:

I have 2 bookings in the DB -> FROM 2022-02-03 TO 2022-02-05 and 2022-01-28 TO 2022-01-29 both property_id = 1, room_id respectively 1 and 2 and this query instead of returning nothing, returns
2022-01-28 TO 2022-01-29

SQL
SELECT *
FROM bookings as b
        JOIN booked_rooms br on b.id = br.booking_id
WHERE b.property_id = 2
    AND br.room_id = 3
    AND b.check_in >= '2022-01-28' AND b.check_in < '2022-01-30'
   OR b.check_out > '2022-01-28' AND b.check_out < '2022-01-30'
   OR b.check_in < '2022-01-28' AND b.check_out > '2022-01-30'

I also tried like that expecting that it would return 1 booking but it does not return anything.

SQL
SELECT *
FROM booked_rooms as br
         JOIN bookings b on br.booking_id = b.id
WHERE b.property_id = 1
  AND br.room_id = 1
  AND '2022-01-28' > b.check_out
  AND '2022-01-29' < b.check_in
Posted
Updated 21-Jan-22 8:44am
v2
Comments
CHill60 20-Jan-22 9:57am    
Share your sample data
Wendelius 20-Jan-22 10:24am    
The queries seem to return data about bookings, not about available rooms. Is this only a portion of the actual query?

AND has precendence over OR, just like multiplication has over addition, so you need parentheses, as in:
SQL
...
AND ((b.check_in >= '2022-01-28' AND b.check_in < '2022-01-30')
  OR (b.check_out > '2022-01-28' AND b.check_out < '2022-01-30')
  OR (b.check_in < '2022-01-28' AND b.check_out > '2022-01-30'))


FYI: only the outer parentheses are required, however I tend to put them all in as that makes it even more readable IMHO.
 
Share this answer
 
v2
Comments
Member 15471521 20-Jan-22 12:08pm    
I tried it and it does not return the room that is not in the DB (roomId=3, propertyId=2) however when I checked to see if it will return an existing booking with an existing room (roomId=1, propertyId=1, 28th till 29th ) it returns nothing.
Luc Pattyn 20-Jan-22 12:15pm    
your data has property_id = 1 and your query requests property_id = 2 so an empty set is the correct result. If you hope for something else your query isn't appropriate.
Member 15471521 20-Jan-22 13:09pm    
Yes, that is correct, empty set result for the propertyId=2 with room id=3 (not in the DB). However shouldn't this query return something if there is a match? For example I tried b.check_in > '2022-01-28' and b.check_out < '2022-01-29', b.property_id = 1, br.room_id = 1 but it returns nothing. My idea was to check if a room is/is not booked (that is - is/is not in the booked_rooms table).Probably I am not going about it the right way.
Member 15471521 20-Jan-22 13:29pm    
Sorry, I found where the mistake is, I was checking the dates 28-29 with wrong roomId and expecting something else. Now I get data when there is a match and no data when there is no match which is what I expect. It works for now :) Thank you so much.
Luc Pattyn 20-Jan-22 13:32pm    
you're welcome.
Adding to solution 1: Taken that you're actually looking for available rooms, not only bookings the query could look something like
SQL
SELECT ...
FROM Rooms r
WHERE r.Room_Id NOT IN 
      (SELECT br.room_id
       FROM bookings as b
       INNER JOIN booked_rooms br on b.id = br.booking_id
       WHERE b.property_id = 2
       AND   (  (b.check_in >= '2022-01-28' AND b.check_in < '2022-01-30')
             OR (b.check_out > '2022-01-28' AND b.check_out < '2022-01-30')
             OR (b.check_in < '2022-01-28' AND b.check_out > '2022-01-30'))

However, this probably doesn't correctly take into account the duration of the stay if it only checks if a room is available during specified dates. So the actual query should check that there is enough continuous availability for the room between a date range which probably can be larger than the desired length of the stay.
 
Share this answer
 
v2
Comments
Member 15471521 20-Jan-22 12:31pm    
My idea was to check if a room is/is not booked (that is - is/is not in the booked_rooms table which is joined with the bookings table which has the dates.Probably I am not going about it the right way.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900