Хорошо, во-первых, используемый вами внутренний запрос является декартовым соединением и будет ОЧЕНЬ дорогим.Вам необходимо указать критерии объединения (например, roombooking_room.booking_id = roombooking.id
).
Во-вторых, если у вас есть диапазон дат, что мы можем сказать по этому поводу?Ну, давайте назовем начало вашего диапазона rangeStartDate
и rangeEndDate
.
Теперь, что мы можем сказать о любом другом диапазоне дат, который не имеет формы перекрытия с этим диапазоном?Ну, endDate
не должно быть между rangeStartDate
и rangeEndDate
.То же самое с startDate
.И rangeStartDate
(и rangeEndDate
, но нам не нужно его проверять) не может быть между startDate
и endDate
...
Итак, предположим, что %1$s
равно rangeStartDate
и %2$s
- это rangeEndDate
, всестороннее предложение where может быть следующим:
WHERE `roomBooking`.`startDate` NOT BETWEEN %1$s AND %2s
AND `roomBooking`.`endDate` NOT BETWEEN %1$s AND %2$$s
AND %1s NOT BETWEEN `roomBooking`.`startDate` AND `roomBooking`.`endDate`
Но есть более простой способ сказать это.Единственный способ для диапазона быть за пределами другого - это чтобы start_date был после end_date, или end_date был до start_id
Итак, предполагая, что %1$s
равно rangeStartDate
, а %2$s
равно rangeEndDate
, еще одно подробное предложение where:
WHERE `roomBooking`.`startDate` > %2$s
OR `roomBooking`.`endDate` < %1$s
Итак, ваш общий запрос выглядит так:
SELECT `id`
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` > %2$s
OR `roomBooking`.`endDate` < %1$s)
)
AND `room`.`maxGuests`>=%d
Есть и другие способы сделать это, так что продолжайте искать...