Это классическая проблема, и на самом деле проще, если вы измените логику.
Позвольте привести пример.
Я опубликую здесь один период времени и все различные варианты других периодов, которые каким-то образом перекрываются.
|-------------------| 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
тогда вы найдете все те, которые не перекрываются, и затем вы найдете все несовпадающие периоды.
В последнем примере NOT IN LIST вы можете видеть, что он соответствует этим двум правилам.
Вам нужно будет решить, находятся ли следующие периоды ВНУТРИ или ВНЕ ваших диапазонов:
|-------------|
|-------| 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)
Обратите внимание на НЕ там. Так как два простых правила находят все несоответствующие строки, простое NOT обратит его к следующему: , если это не одна из несоответствующих строк, это должна быть одна из подходящих те .
Применяя здесь простую логику разворота, чтобы избавиться от НЕ, и в итоге вы получите:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start