Bu klasik bir sorundur ve mantığı tersine çevirirseniz aslında daha kolaydır.
Sana bir örnek vereyim.
Burada bir dönemi ve bir şekilde çakışan diğer dönemlerin tüm farklı varyasyonlarını yayınlayacağım.
|-------------------| 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
Öte yandan, çakışmayanların hepsini göndermeme izin verin:
|-------------------| compare to this one
|---| ends before
|---| starts after
Dolayısıyla, basitçe karşılaştırmayı şu şekilde azaltın:
starts after end
ends before start
daha sonra çakışmayanların hepsini bulacaksınız ve ardından eşleşmeyen tüm dönemleri bulacaksınız.
Son olarak LİSTEDE DEĞİL örneğiniz için, bu iki kuralla eşleştiğini görebilirsiniz.
Aşağıdaki dönemlerin aralıklarınızın İÇİNDE veya DIŞINDA olup olmadığına karar vermeniz gerekecektir:
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
Tablonuzda range_end ve range_start adlı sütunlar varsa, işte tüm eşleşen satırları almak için bazı basit SQL'ler:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Not DEĞİL içeride. İki basit kural tüm eşleşmeyen satırları bulduğundan , basit bir DEĞİL bunu tersine çevirerek şunu söyleyecektir: eğer eşleşmeyen satırlardan biri değilse, eşleşen olanlardan biri olmalıdır .
NOT'dan kurtulmak için burada basit tersine çevirme mantığı uyguladığınızda şununla sonuçlanacaksınız:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start