Це класична проблема, і насправді простіше, якщо ви перейдете логіку.
Дозвольте навести вам приклад.
Я розміщу тут один проміжок часу, і всі різні варіанти інших періодів, які певним чином перетинаються.
|-------------------| 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)
Зверніть увагу на НЕ . Оскільки два простих правила знаходять всі невідповідні рядки, простий НЕ поверне це слово: якщо це не один із невідповідних рядків, він повинен бути одним із відповідних .
Застосовуючи тут просту логіку зміни, щоб позбутися від НЕ, і ви закінчите:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start