Arhn - архитектура программирования

MySQL / PHP - поиск доступных временных интервалов

Было задано несколько вопросов по аналогичным темам, но я не могу найти решение этой конкретной проблемы и был бы благодарен за ваш вклад.

Я работаю над системой бронирования, где пользователи могут бронировать определенные услуги онлайн. Я застрял на поиске и отображении доступных временных интервалов в течение определенного дня (или недели). Я знаю длину необходимого временного интервала (например, 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.

Обратите внимание, что даже если время может перекрываться (как в данных выборки), доступный временной интервал не может перекрываться.
< br /> Как вы думаете, как лучше всего подойти к этому?

16.11.2012

  • Какие условия перекрытия? Предназначены ли они для бронирования услуг с одним человеком, или может происходить несколько встреч одновременно? 16.11.2012
  • Это для бронирования одного человека. Обычный пользователь сможет забронировать только 100% бесплатный временной интервал, т.е. нет перекрытия. У администраторов есть другой / сложный календарь, который допускает перекрытия (поскольку они могут знать, что могут справиться с перекрытием в определенных ситуациях). Что касается вопроса выше, я полагаю, что единственным важным моментом является то, что в таблице базы данных могут быть перекрывающиеся слоты, в которых система должна попытаться найти доступность. 16.11.2012

Ответы:


1
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 (целое число), 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;

Дает вам три самых коротких доступных слота (т. Е. Ближайших к целевому размеру) в окне.

16.11.2012
  • Отлично, спасибо вам большое! Это именно то, что я искал! Как вы думаете, можно ли было бы тоже получить результат по всем имеющимся слотам. В приведенном выше примере одна строка результатов: 2012-11-16 16:00:00 - 2012-11-17 12:00:00. Вместо этого я бы предпочел много строк, содержащих временные интервалы, например: 2012-11-16 16:00:00 - 2012-11-16 17:00:00 и 2012-11-16 17:00:00 - 2012 -11-16 18:00:00 и так далее ... Или вы бы позже разбили все свободное время на слоты, используя PHP? 17.11.2012
  • Еще одна вещь: я поигрался с вашим решением и нашел одну сложную проблему, которую не могу решить самостоятельно. Если я использую ваш оператор с start_of_search_window 2012-11-16 00:00:00 и end_of_search_window 2012-11-18 00:00:00, он пропускает свободный блок между 2012-11-16 00:00:00 и 2012-11- 16 13:00:00. Т.е. он начинается с free_from только после первой найденной встречи. Можете ли вы указать мне правильное направление, как исправить эту ошибку ..? 19.11.2012
  • Концептуально это тривиально - просто замените таблицу bookings a на vierw, который включает фиктивную встречу, заканчивающуюся в начале вашего окна, - но SQL намного сложнее. 19.11.2012
  • Может быть тривиально, но мне не удалось настроить пол и потолок для этого запроса. 11.04.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..