Я совершенно застрял в следующем вопросе. У меня есть серия таблиц:
Я хочу получить всю информацию о комнате, предполагая, что количество заказов не превышает номер комнаты, доступный для этой комнаты.
Итак, чтобы получить информацию о моем номере, мой SQL:
SELECT Rooms.RoomID as RoomID, RoomName, NumOfRooms, MaxPeopleExistingBeds, MaxExtraBeds, MaxExtraPeople, CostPerExtraPerson, MaximumFreeChildren, IncludeBreakfast, MinRate FROM Rooms, RoomDetails WHERE Rooms.AccommodationID = :aid AND Rooms.RoomID = RoomDetails.RoomID GROUP BY RoomName
Который после возвращения получает мне список деталей для этих комнат следующим образом:
Затем я использую этот запрос, чтобы получить количество заказов и идентификатор комнаты:
SELECT Booking.RoomID, count(Booking.RoomID) as Bookings FROM Booking WHERE ArriveDate >= :aDate AND DepartDate <= :dDate AND AccommodationID = :aid GROUP BY RoomID
Затем я объединяю оба и подаю два массива обратно в один массив, используя эту функцию:
public function get_availability($aid, $aDate, $dDate) { $stmt = $this->db->prepare('SELECT Rooms.RoomID as RoomID, RoomName, NumOfRooms, MaxPeopleExistingBeds, MaxExtraBeds, MaxExtraPeople, CostPerExtraPerson, MaximumFreeChildren, IncludeBreakfast, MinRate FROM Rooms, RoomDetails WHERE Rooms.AccommodationID = :aid AND Rooms.RoomID = RoomDetails.RoomID GROUP BY RoomName'); $stmt->bindValue(':aid', $aid); $stmt->execute(); $rooms = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt2 = $this->db->prepare('SELECT Booking.RoomID, count(Booking.RoomID) as Bookings FROM Booking WHERE ArriveDate >= :aDate AND DepartDate <= :dDate AND AccommodationID = :aid GROUP BY RoomID'); $stmt2->bindValue(':aid', $aid); $stmt2->bindValue(':aDate', $aDate); $stmt2->bindValue(':dDate', $dDate); $stmt2->execute(); $bookings = $stmt2->fetchAll(PDO::FETCH_ASSOC); $room = array($rooms, $bookings); return (!empty($room)) ? $room : false; }
Дело в том, что я действительно хочу только вернуть детали комнаты, где NumOfRooms меньше, чем количество Бронировок.
Так, например, если у меня есть $ bookings, если он говорит мне, что для номера ID 4 у меня есть 3 заказа за определенный период, а мои NumOfRooms равны 1. Тогда я знаю, что у меня нет возможности на этой неделе, чтобы сделать больше заказов на , Если, однако, у меня есть 1 заказ и одна емкость, то это все еще заполнено. Но если у меня есть NumOfRooms 2, и количество заказов составляет 1, я знаю, что у меня есть комната.
Так что в принципе, если NumOfRooms> BookingCount, тогда номер доступен.
Как я могу объединить оба запроса и упростить мой код, чтобы сделать это возможным?
IE, чтобы просто сказать, как я могу выбрать всю информацию из RoomDetails с учетом ArriveDate в бронировании, а также DepartAutate и RoomID, где NumOfRooms> count (Booking.RoomID) (где он находится в этих датах, а идентификатор номера равен к номеру комнаты Комнат).
Ваша проблема может быть решена путем простого обновления самой инструкции SQL:
SELECT r.RoomID AS RoomID, RoomName, NumOfRooms, MaxPeopleExistingBeds, MaxExtraBeds, MaxExtraPeople, CostPerExtraPerson, MaximumFreeChildren, IncludeBreakfast, MinRate FROM Rooms r JOIN RoomDetails rd ON r.RoomID = rd.RoomID JOIN ( SELECT b.RoomID, AccommodationID, count(b.RoomID) AS Bookings FROM Booking b WHERE ArriveDate >= :aDate AND DepartDate <= :dDate GROUP BY RoomID ) t ON t.AccommodationID = r.AccommodationID WHERE r.AccommodationID = :aid AND t.Bookings < NumOfRooms GROUP BY RoomName
Вы можете выбрать все подсчеты бронирования в комнате для нужного диапазона дат в качестве подзапроса, а затем LEFT JOIN
чтобы подзапрос в списке ваших комнат был отфильтрован по вашему желаемому NumOfRooms > BookingCount
AccommodationID
и нужным NumOfRooms > BookingCount
. Ключевым здесь является тип соединения, используемый для этого подзапроса, поскольку внутреннее соединение ограничивает ваши результаты только теми комнатами, на которых действительно были заказы.
SELECT Rooms.RoomID as RoomID, RoomName, NumOfRooms, MaxPeopleExistingBeds, MaxExtraBeds, MaxExtraPeople, CostPerExtraPerson, MaximumFreeChildren, IncludeBreakfast, MinRate, BookingCount FROM Rooms INNER JOIN RoomDetails on Rooms.RoomID = RoomDetails.RoomID LEFT JOIN ( SELECT Booking.RoomID, count(Booking.RoomID) as BookingCount FROM Booking WHERE ArriveDate >= :aDate AND DepartDate <= :dDate GROUP BY Booking.RoomID ) RoomBookings ON Rooms.RoomID = RoomBookings.RoomID WHERE Rooms.AccommodationID = :aid AND NumOfRooms > BookingCount GROUP BY RoomName