Довольно частая задача при работе с различными событиями и датами.
Имеется таблица вида:
CREATE TABLE `event` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `start_time` datetime DEFAULT NULL, `end_time` datetime DEFAULT NULL, );
Тут start_time
и end_time
не обязательно datetime
. Например, они могут быть просто int
-ами, хранящими обычный unix timestamp.
Перед вставкой очередной записи нужно убедиться, что событие не пересечётся с каким-либо уже имеющимся в базе. Решается это так:
SELECT 1 FROM event WHERE :new_start_time BETWEEN start_time AND end_time OR :new_end_time BETWEEN start_time AND end_time OR start_time BETWEEN :new_start_time AND :new_end_time OR end_time BETWEEN :new_start_time AND :new_end_time LIMIT 1
В запросе :new_start_time
и :new_end_time
соответственно начало и конец события, которое мы собираемся вставлять. Если запрос выше отдал 1
, наше новое событие с чем-то пересекается…
UPD: менее избыточные варианты (спасибо dec5e):
NOT(:new_start_time > end_time OR :new_end_time < start_time)
или через AND
:new_start_time <= end_time AND :new_end_time >= start_time