В MySQL, если у меня есть список диапазонов дат (начало и конец диапазона). например
10/06/1983 to 14/06/1983
15/07/1983 to 16/07/1983
18/07/1983 to 18/07/1983
И я хочу проверить, содержит ли другой диапазон дат ЛЮБОЙ из диапазонов, уже включенных в список, как мне это сделать?
например
06/06/1983 to 18/06/1983 = IN LIST
10/06/1983 to 11/06/1983 = IN LIST
14/07/1983 to 14/07/1983 = NOT IN LIST
Ответы:
Это классическая проблема, и ее действительно проще, если вы перевернете логику.
Позвольте привести пример.
Я размещу здесь один период времени и все различные вариации других периодов, которые так или иначе перекрываются.
с другой стороны, позвольте мне опубликовать все, что не пересекается:
Итак, если вы просто уменьшите сравнение до:
тогда вы найдете все те, которые не пересекаются, а затем вы найдете все несовпадающие периоды.
В вашем последнем примере НЕ В СПИСКЕ вы можете видеть, что он соответствует этим двум правилам.
Вам нужно будет решить, находятся ли следующие периоды В или ВНЕ ваших диапазонов:
Если в вашей таблице есть столбцы с именами range_end и range_start, вот простой SQL для извлечения всех совпадающих строк:
Обратите внимание на НЕ там. Поскольку два простых правила находят все несовпадающие строки, простое НЕ изменит его, чтобы сказать: если это не одна из несовпадающих строк, она должна быть одной из совпадающих .
Применяя здесь простую логику разворота, чтобы избавиться от НЕ, вы получите:
источник
Взяв ваш примерный диапазон от 06.06.1983 до 18.06.1983 и предполагая, что у вас есть столбцы с названиями start и end для ваших диапазонов, вы можете использовать такое предложение
т.е. убедитесь, что начало вашего тестового диапазона находится перед концом диапазона базы данных, и что конец вашего тестового диапазона находится после или в начале диапазона базы данных.
источник
Если ваша СУБД поддерживает функцию OVERLAP (), тогда это становится тривиальным - нет необходимости в собственных решениях. (В Oracle это явно работает, но недокументировано).
источник
В ваших ожидаемых результатах вы говорите
06.06.1983 по 18.06.1983 = В СПИСОК
Однако этот период не содержит и не входит ни в один из периодов в вашей таблице (не в списке!) Периодов. Однако он совпадает с периодом с 10.06.1983 по 14.06.1983.
Вы можете найти книгу Snodgrass ( http://www.cs.arizona.edu/people/rts/tdbbook.pdf ) полезной: она предшествует mysql, но концепция времени не изменилась ;-)
источник
Я создал функцию для решения этой проблемы в MySQL. Просто преобразуйте даты в секунды перед использованием.
источник
Посмотрите на следующий пример. Это будет вам полезно.
источник
Попробуйте это на MS SQL
источник
источник
Другой метод с использованием инструкции BETWEEN sql
Включенные периоды:
Исключенные периоды:
источник
источник