Как определить, происходит ли диапазон дат в любое время в другом диапазоне дат? - PullRequest
6 голосов
/ 08 апреля 2009

У меня есть таблица событий, в которой указан диапазон дат с полями start_date и end_date. У меня есть другой диапазон дат, указанный в коде, который определяет текущую неделю как 'week_start' и 'Week_end'.

Я бы хотел запросить все события за неделю. Случаи кажутся:

  • Событие начинается и заканчивается в течение недели
  • Событие начинается до недели, но заканчивается в течение недели
  • Событие начинается в течение недели, но заканчивается после недели
  • Событие начинается до недели, а также заканчивается после недели
  • События, которые не находятся ни внутри, ни перекрывают неделю, игнорируются

Я пытаюсь найти запрос, который может обработать все эти случаи. До сих пор я был в состоянии получить только случаи, которые обрабатывают недельные совпадения, или события, которые являются полностью внутренними; По сути, слишком много записей или вообще нет.

Ответы [ 5 ]

21 голосов
/ 08 апреля 2009
(event.start BETWEEN week.start AND week.end)
OR
(week.start BETWEEN event.start AND event.end)

Проще говоря, либо неделя начинается во время события, либо событие начинается в течение недели.

Давайте проверим это:

Событие начинается и заканчивается в течение недели

Событие начинается в течение недели.

Событие начинается до недели, но заканчивается в течение недели

Неделя начинается во время мероприятия.

Событие начинается в течение недели, но заканчивается после недели

Событие начинается в течение недели.

Событие начинается до недели, а также заканчивается после недели

Неделя начинается во время мероприятия.

Обратите внимание, что BETWEEN в вышеприведенных выражениях используется просто для краткости.

Строгое выражение выглядит так:

(event.start >= week.start AND event.start < week.end)
OR
(week.start >= event.start AND week.start < event.end)

, при условии, что week.end является week.start + INTERVAL 7 DAY.

I. е. если ваша неделя начинается с Sun, 0:00:00, то она должна заканчиваться на next Sun, 0:00:00 (не на Sat, 0:00:00)

Это выражение выглядит сложнее, чем обычно используемое:

event.start < week.end AND event.end > week.start

, но первый более эффективен и удобен для индексов.

См. Эти статьи в моем блоге для сравнения производительности:

3 голосов
/ 08 апреля 2009

Вы можете написать свое состояние так:

start_date <= week_end AND end_date >= week_start

Редактировать: предполагается, что start_date

Edit2: это решение также решает проблему событий, которые начинаются до интервала и заканчиваются после интервала.

2 голосов
/ 18 июня 2009

+ 1 для поп-каталина, но, увы, у меня нет права голоса.

Требуемое условие ограничения - это просто стандартный способ выражения оператора Аллена "OVERLAPS".

Дополнительная оговорка SQL: если end_date имеет значение NULL, убедитесь, что значения NULL в этих столбцах указаны как "конец времени".

Дополнительные функциональные предостережения: не забудьте адаптировать использование '<=' против '<', независимо от того, включают ли записанные периоды времени дату окончания или нет. </p>

0 голосов
/ 08 апреля 2009

(end2> = start1) && (start2 <= end1) Я думаю, что вернул бы true для любых пересекающихся диапазонов дат. </p>

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

0 голосов
/ 08 апреля 2009

В порядке ...

where start_date >= week_start and end_date <= week_end
where start_date <= week_start and end_date >= week_start and end_date <= week_end
where start_date >= week_start and start_date <= week_end and end_date > week_end
where start_date < week_start and end_date > week_end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...