У меня есть система бронирования, в которой мне нужно выбрать любую доступную комнату из базы данных. Базовая настройка такова:
table: room
columns: id, maxGuests
table: roombooking
columns: id, startDate, endDate
table: roombooking_room:
columns: id, room_id, roombooking_id
Мне нужно выбрать комнаты, в которых могут разместиться запрошенные гости, или выбрать две (или более) комнаты, в которые поместятся гости (как определено в maxGests, очевидно, сначала используя maxGests с нижним / шкафом)
Я мог бы перебрать свой диапазон дат и использовать этот sql:
SELECT `id`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`, `roombooking`
WHERE `roombooking`.`confirmed` =1
AND DATE(%s) BETWEEN `roombooking`.`startDate` AND `roombooking`.`endDate`
)
AND `room`.`maxGuests`>=%d
Где% $ 1 - это зацикленная дата, а% 2d - количество гостей, которых нужно зарезервировать. Но это просто вернет false, если гостей больше, чем любого место может занять, и должен быть более быстрый способ сделать это, а не зацикливаться с php и запускать запрос?
Это похоже на часть sql, о которой я думал: Получение дат между диапазоном дат , но с решением Mysql
, основанным на ответе ircmaxwell:
$query = sprintf(
"SELECT `id`, `maxGuests`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`
JOIN `roombooking` ON `roombooking_room`.`roombooking_id` = `roombooking`.`id`
WHERE `roombooking`.`confirmed` =1
AND (`roomBooking`.`startDate` > DATE(%s) OR `roomBooking`.`endDate` < DATE(%s))
)
AND `maxGuests` <= %d ORDER BY `maxGuests` DESC",
$endDate->toString('yyyy-MM-dd'), $startDate->toString('yyyy-MM-dd'), $noGuests);
$result = $db->query($query);
$result = $result->fetchAll();
$rooms = array();
$guests = 0;
foreach($result as $res) {
if($guests >= $noGuests) break;
$guests += (int)$res['maxGuests'];
$rooms[] = $res['id'];
}