Това е класически проблем и всъщност е по-лесно, ако обърнете логиката.
Нека ви дам пример.
Тук ще публикувам един период от време и всички различни варианти на други периоди, които се припокриват по някакъв начин.
|-------------------| 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