Мой опыт работы с БД не намного больше, чем простое хранение + извлечение данных в стиле CMS - так что это может быть глупый вопрос, я не знаю!
У меня есть проблема, из-за которой мне нужно искать или рассчитывать отпускные цены для определенного размера группы и определенного количества дней в течение определенного периода времени. Например:
Сколько стоит номер в гостинице для 2 человек на 4 ночи в любое время в январе?
У меня есть данные о ценах и наличии, скажем, 5000 отелей, которые хранятся примерно так:
Hotel ID | Date | Spaces | Price PP
-----------------------------------
123 | Jan1 | 5 | 100
123 | Jan2 | 7 | 100
123 | Jan3 | 5 | 100
123 | Jan4 | 3 | 100
123 | Jan5 | 5 | 100
123 | Jan6 | 7 | 110
456 | Jan1 | 5 | 120
456 | Jan2 | 1 | 120
456 | Jan3 | 4 | 130
456 | Jan4 | 3 | 110
456 | Jan5 | 5 | 100
456 | Jan6 | 7 | 90
С помощью этой таблицы я могу сделать запрос следующим образом:
SELECT hotel_id, sum(price_pp)
FROM hotel_data
WHERE
date >= Jan1 and date <= Jan4
and spaces >= 2
GROUP BY hotel_id
HAVING count(*) = 4;
Результаты
hotel_id | sum
----------------
123 | 400
HAVING
Пункт здесь убеждается , что есть запись для каждого дня между моей датой , которая имеет пространство доступно. то есть. В отеле 456 было 1 место, доступное 2 января, предложение HAVING вернуло бы 3, поэтому мы не получаем результат для отеля 456.
Все идет нормально.
Тем не менее, есть ли способ узнать все 4 ночи в январе, где есть свободное место? Мы могли бы повторить запрос 27 раз - увеличивая даты каждый раз, что кажется немного неловким. Или другой путь может заключаться в том, чтобы хранить все возможные комбинации в таблице поиска следующим образом:
Hotel ID | total price pp | num_people | num_nights | start_date
----------------------------------------------------------------
123 | 400 | 2 | 4 | Jan1
123 | 400 | 2 | 4 | Jan2
123 | 400 | 2 | 4 | Jan3
123 | 400 | 3 | 4 | Jan1
123 | 400 | 3 | 4 | Jan2
123 | 400 | 3 | 4 | Jan3
И так далее. Нам нужно ограничить максимальное количество ночей и максимальное количество людей, которых мы будем искать - например, максимальное количество ночей = 28, максимальное количество людей = 10 (ограничено количеством мест, доступных для этого установленного периода, начинающегося с этой даты).
Для одного отеля это может дать нам 28 * 10 * 365 = 102000 результатов в год. 5000 отелей = 500м результатов!
Но у нас был бы очень простой запрос, чтобы найти самый дешевый 4 ночи в январе для 2 человек:
SELECT
hotel_id, start_date, price
from hotel_lookup
where num_people=2
and num_nights=4
and start_date >= Jan1
and start_date <= Jan27
order by price
limit 1;
Есть ли способ выполнить этот запрос к исходной таблице, не создавая таблицу поиска строк длиной 500 м !? например, сгенерировать 27 возможных результатов во временной таблице или какую-то другую магию внутренних запросов?
В настоящий момент все данные хранятся в БД Postgres - если для этого потребуется, мы можем переместить данные в другое, более подходящее место? Не уверен, что этот тип запроса соответствует шаблонам карты / сокращения для БД в стиле NoSQL ...