Допустим, у вас есть база отелей. Каждый отель создает в базе данных много тарифов, каждый из которых имеет from_date
и to_date
. Тарифы гарантированно никогда не перекрываются.
В каждом тарифе менеджер отеля может установить минимальное пребывание на этот период. Например, с 1 декабря по 30 января минимальный срок пребывания составляет 10 ночей.
Теперь путешественник вводит свои даты, например, с 25 декабря по 1 января. В этом случае, этот отель не должен быть возвращен в результатах, потому что с 1 декабря по 30 января действует тариф, который определяет только пребывание не менее 10 ночей.
Я не могу придумать способ запроса этой базы данных (используя SQL или Elasticsearch, который является нашей поисковой системой на данный момент), чтобы избежать возвращения отелей с более высоким минимальным пребыванием в этом диапазоне дат.
В SQL я бы исследовал путь, joining
таблицу Hotels с таблицей тарифов, используя WHERE
чтобы получить тарифы, которые перекрывают даты, желаемые путешественником (возможно, с использованием (StartA <= EndB) and (EndA >= StartB)
), плюс агрегатная функция, такая как MAX()
чтобы получить максимальное min_stay
найденных тарифов, и, наконец, HAVING
чтобы указать его, должно быть> затем min_stay
ночей, которое существует в диапазоне, предоставленном путешественником.
Но даже этот путь для меня неясен, поскольку, когда я присоединяюсь к столу, я исключаю отели без каких-либо настроенных тарифов, а это нежелательно; может быть, левое внешнее соединение? И как перевести это наasticsearch должно быть еще более сложной задачей (возможно, с использованием чего-то вроде агрегации ведра, описанной здесь qaru.site/questions/2437667/...)
Вот приблизительная схема запроса. Предполагается, что конечная дата для тарифов включительно.
SET @checkin = '2018-12-25';
SET @checkout = '2019-01-01';
SET @date1 = @checkin;
SET @date2 = @checkout - INTERVAL 1 DAY;
SET @nights = DATEDIFF(@checkout, @checkin);
SELECT *
FROM hotels
WHERE NOT EXISTS (
SELECT 1
FROM hotel_rates
WHERE hotel_id = hotels.id
AND @date2 >= from_date AND to_date >= @date1
AND min_stay > @nights
)
Он проверяет, что для каждого отеля не существует тарифа, который пересекает данный диапазон дат и требует минимального пребывания, превышающего количество ночей.