На подобные темы было задано несколько вопросов, но я не могу найти решение этой конкретной проблемы и был бы благодарен за ваш вклад.
Я работаю над механизмом бронирования, где пользователи могут забронировать определенные услуги в Интернете. Я застрял в поиске и отображении доступных временных интервалов в течение определенного дня (или недели). Я знаю длину требуемого временного интервала (например, 1 час) и рабочие часы, в которые можно зарезервировать временные интервалы (например, с 09:00 до 18:00). Кроме того, у меня есть таблица MySQL, в которой хранятся уже существующие встречи. Столбцы, относящиеся к моим вопросам, выглядят следующим образом:
id start (datetime) end (datetime) 1 '2012-11-16 13:00:00' '2012-11-16 14:30:00' 2 '2012-11-16 15:00:00' '2012-11-16 16:00:00' 3 '2012-11-17 12:00:00' '2012-11-16 15:45:00' 4 '2012-11-17 13:00:00' '2012-11-16 16:15:00' ...
Теперь, учитывая информацию, указанную выше, я не могу найти хорошее решение (в MySQL или PHP) для получения списка доступных временных интервалов. Есть еще одно условие: временные интервалы могут начинаться только ежеквартально. То есть. для приведенных выше примерных данных на 16-м доступных одночасовых временных слотах будет:
09:00, 09:15, 09:30, 09:45, 10:00, …, 12:00, 16:00, 16:15, …, 17:00.
Обратите внимание, что хотя время перекрытия может быть перекрыто (как в данных образца), доступный временной интервал не может перекрываться.
Как вы думаете, как лучше всего подойти к этому?
SELECT a.end AS free_after FROM bookings a WHERE NOT EXISTS ( SELECT 1 FROM bookings b WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOURS ) AND a.end BETWEEN start_of_search_window AND end_of_search_window;
вам просто нужно указать значения для your_duration
(integer), start_of_search_window
(время даты) и end_of_search_window
(время даты).
А если хочешь колокола и свистки ….
SELECT free_from, free_until FROM ( SELECT a.end AS free_from, (SELECT MIN(c.start) FROM bookings c WHERE c.start > a.end) as free_until FROM bookings a WHERE NOT EXISTS ( SELECT 1 FROM bookings b WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOUR ) AND a.end BETWEEN start_of_search_window AND end_of_search_window ) ORDER BY free_until-free_from LIMIT 0,3;
Вы получите три самых коротких доступных слота (то есть ближайший размер цели) в окне.