To klasyczny problem i jest łatwiejszy, jeśli odwrócisz logikę.
Dam ci przykład.
Opublikuję tutaj jeden okres i wszystkie różne odmiany innych okresów, które w jakiś sposób się pokrywają.
|-------------------| 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
z drugiej strony pozwól mi opublikować wszystkie te, które się nie pokrywają:
|-------------------| compare to this one
|---| ends before
|---| starts after
Więc jeśli po prostu zredukujesz porównanie do:
starts after end
ends before start
wtedy znajdziesz wszystkie te, które się nie pokrywają, a potem znajdziesz wszystkie niepasujące okresy.
W ostatnim przykładzie NIE NA LIŚCIE widać, że pasuje do tych dwóch reguł.
Będziesz musiał zdecydować, czy następujące okresy znajdują się w twoich zakresach, czy poza nimi:
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
Jeśli Twoja tabela zawiera kolumny o nazwach range_end i range_start, oto kilka prostych instrukcji SQL do pobrania wszystkich pasujących wierszy:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Zwróć uwagę na NIE w tym miejscu. Ponieważ dwie proste reguły znajdują wszystkie niepasujące wiersze, proste NOT odwróci to, mówiąc: jeśli nie jest to jeden z niepasujących wierszy, musi to być jeden z pasujących wierszy .
Stosując tutaj prostą logikę odwrócenia, aby pozbyć się NOT, a otrzymasz:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start