вы хотели бы исключить комнаты, где резервирования имеют перекрытие с диапазоном дат запроса.
, то есть
$queryBuilder->expr()->lt('r.start', '?1'), // 1 being stop
$queryBuilder->expr()->gt('r.stop', '?2'), // 2 being start
, который вы уже правильно указали. однако ваша нулевая проверка выключена, она должна быть:
$queryBuilder->expr()->isNull('r') // <-- you had rm here
, поэтому, r
, очевидно, является резервированием, и это должно быть нулевым («отсутствующим»).
(Я всегда нахожу, что использование коротких псевдонимов очень усложняет обнаружение таких ошибок, и при этом экономится очень мало фактического времени ..., я также предпочитаю именованные параметры над пронумерованными параметрами)
обновление
Хорошо, я пропустил главное, что здесь не так; o /
Ваш запрос соответствует всем комнатам с всеми бронированиями (не только бронированием этой комнаты) и выбирает те, которые «не имеют» брони. Значение: если есть резервирование для диапазона дат, вы возвращаете НЕТ номеров, а если нет резервирования для диапазона дат, вы возвращаете ВСЕ номера.
Есть два способа заставить построителя запросов выполнитьправильно, что зависит от вашего определения отображения, но я буду предполагать, что у сущности Room
есть поле reservations
, которое содержит все резервирования для этой комнаты.
$qb->from('Room', 'rm')
->leftJoin('rm.reservations', 'r', 'WITH', ...)
Разница в том, чтодескриптор "table" подразумевает , что резервирование относится к соответствующей комнате и объединено только с этим.
Или является явным:
$qb->from('Room', 'rm')
->leftJoin('Reservation', 'r', 'WITH', $qb->expr()->andX('r.room=rm', ...))
Это должно окончательно решить вашу проблему.