简体   繁体   English

当一个预订中有多个类别时,获取两个日期之间的可用房间

[英]Get available room between two dates when there are multiple category in one booking

My problem is I'm lost as to what to do when getting the available room between 2 dates when the bookings can have multiple room type in one booking. 我的问题是,当预订在一个预订中可以有多个房间类型时,我无法确定在两个日期之间获得可用房间时该怎么办。

I have 3 tables: 我有3张桌子:

reservedRoom reservedRoom

    create table reservedRoom (
bookingID int ,
roomID int NOT NULL,
n_person int,
)



bookingID   roomID  n_person
2            1          2
2            2          2
2            3          3
2            4          3
2            5          3

room 房间

create table room (
roomID int NOT NULL PRIMARY KEY,
descriptions int NOT NULL,
rate int,
category varchar(30),
)
roomID  descriptions    rate    category
1              2        2000    standard
2              2        2000    standard
3              2        2000    standard
4              2        2000    standard
5              2        2000    standard
6              2        2000    standard
7              2        2000    standard
8              2        2000    standard
9              2        2500    quad
10             2        2500    quad
11             2        2500    quad
12             2        2500    quad
13             2        2500    quad
14             2        3000    family
15             2        3000    family
16             2        3000    family
17             2        3000    family
18             2        8000    King
19             2        8000    King
20             2        8000    King

Booking 预订

create table bookings (
bookingID int NOT NULL PRIMARY KEY,
clientID int NOT NULL,
checkIndate DATETIME,
checkOutDate DATETIME,
roomsCount int,
numNights int,
bookExpire DATETIME,
)

   bookingID    clientID    checkIndate checkOutDate    roomsCount  numNights   bookExpire
1                 1        2018-02-08   2018-02-09      3             2     2018-02-11 
2                 2        2018-02-08   2018-02-09      5             2     2018-02-11 
3                 3        2018-02-08   2018-02-09      3             2     2018-02-11 
4                 4        2018-02-08   2018-02-09      3             2     2018-02-11 
5                 5        2018-02-08   2018-02-09      3             2     2018-02-11 

I tried this code but I don't know what to do from here. 我尝试了这段代码,但是我不知道该怎么办。

 $availableRooms = booking::where(function($query) use ($checkInDate_1, $checkOutDate_1)
                {
                  $query->where(function($query) use ($checkInDate_1, $checkOutDate_1){
                      $query->whereDate('bookings.checkOutDate', '>=', $checkInDate_1);
                      $query->whereDate('bookings.checkOutDate', '<=', $checkOutDate_1);
                  });
                })
              ->whereDate('bookings.bookExpire', '>',$checkOutDate_1)
              ->get();

My problem is that how do i group the rooms by bookingID and integrate that group to the query to get the rooms available at checkIn and checkOut. 我的问题是,如何将我的房间按BookingID分组,并将该组集成到查询中,以在checkIn和checkOut处获得可用的房间。

Desired Result for date 2018-02-08 - 2018-02-09 日期的期望结果 2018-02-08-2018-02-09

standard room - 3 Rooms available
quad room - 5 rooms available
family room - 4 rooms available
king room - 3 rooms available

Here is an example of how to go about with the query 这是如何进行查询的示例

First step, find out the current number of a rooms, grouped by category for the bookings 第一步,找出当前房间数,按预订类别分组

After that subtract the value by category with the total rooms grouped by category from the room table 然后,从类别表中减去类别值,然后从类别表中减去类别总数

   select x.category
          ,count(x.roomId) - case when isnull(max(booked_rooms.cnt))=1 then
                                       0
                                  else max(booked_rooms.cnt)
                                  end as available_rooms
     from room x
left join ( select c.category /* Find out the rooms bny category which are booked within the dates*/
                  ,count(c.roomID) as cnt
              from bookings a
              join reservedRoom b
                on a.bookingID=b.bookingID
              join room c
                on b.roomID=c.roomID
            where a.checkIndate between '2018-02-08' and '2018-02-09' 
            group by c.category
           )booked_rooms
        on x.category=booked_rooms.category
 group by x.category  

Here is a dbfiddle link 这是dbfiddle链接

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8a91f2486bac25bda3f46b6ae3cddf8c https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8a91f2486bac25bda3f46b6ae3cddf8c

You just need a simple range intersection query. 您只需要一个简单的范围交集查询。 This should do it: 应该这样做:

SELECT category, COUNT(*)
FROM room
WHERE NOT EXISTS (
    -- room is booked on the requested dates (...not)
    SELECT 1
    FROM reservedRoom
    JOIN bookings ON reservedRoom.bookingID = bookings.bookingID
    WHERE reservedRoom.roomID = room.roomID
    AND '2018-02-09' > checkIndate
    AND '2018-02-08' < checkOutDate
)
GROUP BY category

Your sql request will be 您的sql请求将是

select r.category, count(*) as [count]
from room as r
    left join reservedRoom as rr
        on r.roomID = rr.roomID
    left join bookings as b
        on rr.bookingID = b.bookingID
            and ((b.checkIndate >= @DateFrom and b.checkIndate < @DateTo)
                or (b.checkOutDate > @DateFrom and b.checkOutDate <= @DateTo)
            )
where b.bookingID is null
group by r.category

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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