Получить доступные апартаменты

#php #mysql

#php #mysql

Вопрос:

Таблица апартаментов:

таблица апартаментов

бронирование:

Мне нужны все доступные апартаменты, которые не забронированы. Это мой текущий запрос mysql:

 (array) $db->getRecords('
SELECT i.id, i.num_persons, i.rating, i.lat, i.lng, i.street, i.number,
  c.title, c.introduction, c.text, c.area, c.long_term_rental, c.beds, c.features, 
  c.services_and_equipment, c.terms_and_conditions, m.url
FROM appartments AS i
INNER JOIN appartments_content AS c on c.parent_id = i.id
INNER JOIN meta AS m on m.id = c.meta_id
LEFT JOIN appartments_bookings AS b on b.appartment_id = i.id
WHERE c.language = ? 
  AND i.hidden = ? 
  AND i.publish_on <= ? 
  AND i.city_id = ? 
  AND i.num_persons >= ? 
  AND (b.arrival >= ? OR b.departure <= ?)
ORDER BY i.num_persons ASC, i.publish_on DESC
LIMIT ?, ?',

array( FRONTEND_LANGUAGE, 'N', FrontendModel::getUTCDate('Y-m-d H:i') . ':00', 
  (int) $filter['city'], (int) $filter['persons'], $filter['arrival'],
  $filter['departure'], (int) $offset, (int) $limit), 'id');
  

Комментарии:

1. В чем ваш вопрос? Что насчет запроса, который не работает?

2. Я все равно получаю все апартаменты, даже когда они забронированы.

3. У меня есть записи бронирования с прибытием 2011-09-06 и отправлением 2011-09-08, Если я передам значение 2011-09-07 в качестве прибытия и отъезда в запрос, квартира все равно отображается.

4. Убедитесь, что вы отредактировали свой запрос так, чтобы он выглядел красиво и не прокручивал экран и тому подобное. Это делает гораздо более привлекательным для людей, которые действительно потрудились ответить на ваш вопрос. Не просто копируйте и вставляйте материал и переходите. Только на этот раз я прояснил для вас вопрос 🙂

Ответ №1:

 SELECT a.id, a.num_persons, a.rating, a.lat, a.lng, a.street, a.number
  ,c.title, c.introduction, c.text, c.area, c.long_term_rental, c.beds
  , c.features ,c.services_and_equipment, c.terms_and_conditions
  , m.url
FROM appartments AS a
INNER JOIN appartments_content AS c on c.parent_id = a.id
INNER JOIN meta AS m on m.id = c.meta_id
LEFT JOIN appartments_bookings AS b 
       ON (b.appartment_id = a.id 
      AND NOT ((? > b.departure) OR (? < b.arrival)))    
     --    this ? = arrival     that ? = departure
WHERE b.id IS NULL 
  AND c.language = ? 
  AND a.hidden = ? 
  AND a.publish_on <= ? 
  AND a.city_id = ? 
  AND a.num_persons >= ? 

ORDER BY a.num_persons ASC, a.publish_on DESC
LIMIT ? OFFSET ?'
  

Изменения

тест на занятость
Тест NOT((param_arrival > b.departure) OR (param_departure < b.arrival)) представляет собой простой тест на перекрытие, который работает с 2 тестами. У вас нет, потому что для этого требуется всего 4 теста, так что вы что-то упускаете.
Конечно, этот код предполагает, что прибытие всегда выпадает перед вылетом, поэтому убедитесь, что вы утверждаете это предположение.

Используйте антисоединение при бронировании
Мы помещаем все тесты на занятие в критерии объединения для бронирований.
И затем я выбираю только строки, для которых нет бронирований, т. Е. Для которых b.id РАВНО НУЛЮ.

Предложение LIMIT
Это просто моя любимая мозоль, но я предпочитаю гораздо более интуитивно LIMIT rowcount OFFSET pagestart понятный синтаксис, чем запутанный LIMIT pagestart, rowcount .

Комментарии:

1. У меня есть следующий вопрос. Мне нужно проверить в таблице apartments_booking (single), не отменен ли статус, если он отменен, квартира должна отображаться в результатах. Я отредактировал запрос следующим образом: pastie.org/2711211 (я использовал pastie, потому что ввод символов кажется ограниченным) Но теперь у меня нет результатов. Есть мысли?