Это классическая проблема, и ее действительно проще, если вы перевернете логику.
Позвольте привести пример.
Я размещу здесь один период времени и все различные вариации других периодов, которые так или иначе перекрываются.
|-------------------| compare to this one
|---------| contained within
|----------| contained within, equal start
|-----------| contained within, equal end
|-------------------| contained within, equal start+end
|------------| not fully contained, overlaps start
|---------------| not fully contained, overlaps end
|-------------------------| overlaps start, bigger
|-----------------------| overlaps end, bigger
|------------------------------| overlaps entire period
с другой стороны, позвольте мне опубликовать все, что не пересекается:
|-------------------| compare to this one
|---| ends before
|---| starts after
Итак, если вы просто уменьшите сравнение до:
starts after end
ends before start
тогда вы найдете все те, которые не пересекаются, а затем вы найдете все несовпадающие периоды.
В вашем последнем примере НЕ В СПИСКЕ вы можете видеть, что он соответствует этим двум правилам.
Вам нужно будет решить, находятся ли следующие периоды В или ВНЕ ваших диапазонов:
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
Если в вашей таблице есть столбцы с именами range_end и range_start, вот простой SQL для извлечения всех совпадающих строк:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Обратите внимание на НЕ там. Поскольку два простых правила находят все несовпадающие строки, простое НЕ изменит его, чтобы сказать: если это не одна из несовпадающих строк, она должна быть одной из совпадающих .
Применяя здесь простую логику разворота, чтобы избавиться от НЕ, вы получите:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start