Как эффективно найти все записи, которые НЕ пересекаются с интервалом дат? - PullRequest
3 голосов
/ 07 июня 2011

Допустим, у меня есть таблица hotel_rooms, каждая из которых содержит несколько связанных записей о бронировании.

Таблицы будут выглядеть следующим образом:

hotel_rooms:

hotel_room_id | hotel_name
--------------------------
1             | Hotel A
2             | Hotel B
3             | Hotel C

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

reservation_id | hotel_room_id | start_date   | end_date
------------------------------------------------------------
1              | 1             | 1 June 2011  | 10 June 2011
2              | 1             | 20 June 2011 | 30 June 2011
3              | 2             | 11 June 2011 | 15 June 2011
4              | 3             | 1 June 2011  | 4 June 2011



Как найти все hotel_rooms с checkin_date и checkout_date, которые не совпадают ни с одним избронирование hotel_rooms?

Например, если checkin_date был 4 июня 2011 года, а checkout_date был 8 июня 2011 года, тогда Hotel A и Hotel C не будут отображаться в результатах, только Hotel B. Если checkin_dateбыло 16 июня 2011 года, а checkout_date - 19 июня 2011 года, все три отеля должны были появиться.

Я уверен, что есть несколько способов сделать это, но для нашей ситуации, скажем, есть многоЗаписи в hotel_rooms и каждой комнате связаны со многими записями бронирования.Какой эффективный способ справиться с этим поиском?

В своих целях я использую MySQL и PHP (но мне не обязательно нужно решение, отвечающее какому-либо из них).

Ответы [ 2 ]

3 голосов
/ 07 июня 2011
SELECT h.*
FROM hotel_rooms h
  LEFT JOIN reservations r
    ON h.hotel_room_id = r.hotel_room_id
   AND checkin_date <= r.end_date
   AND checkout_date >= r.start_date
WHERE r.reservation_id IS NULL

или:

SELECT *
FROM hotel_rooms h
  WHERE NOT EXISTS (
    SELECT *
    FROM reservations r
    WHERE h.hotel_room_id = r.hotel_room_id
      AND checkin_date <= r.end_date
      AND checkout_date >= r.start_date
  )
0 голосов
/ 07 июня 2011

Я думаю, что пара подзапросов NOT EXISTS будет работать для вас.Время также не должно быть проблемой, при условии, что таблицы правильно проиндексированы.

SELECT *
FROM hotel_rooms
WHERE NOT EXISTS (SELECT 1 FROM reservations 
                  WHERE reservations.hotel_room_id = hotel_rooms.hotel_room_id
                  AND checkin_date BETWEEN start_date AND end_date)
AND NOT EXISTS (SELECT 1 FROM reservations 
                WHERE reservations.hotel_room_id = hotel_rooms.hotel_room_id 
                AND checkout_date BETWEEN start_date AND end_date)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...