Ini adalah masalah klasik, dan sebenarnya lebih mudah jika Anda membalik logika.
Izinkan saya memberi Anda sebuah contoh.
Saya akan memposting satu periode waktu di sini, dan semua variasi berbeda dari periode lain yang tumpang tindih dalam beberapa cara.
|-------------------| 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
di sisi lain, izinkan saya memposting semua yang tidak tumpang tindih:
|-------------------| compare to this one
|---| ends before
|---| starts after
Jadi, jika Anda sederhana, kurangi perbandingannya menjadi:
starts after end
ends before start
lalu Anda akan menemukan semua yang tidak tumpang tindih, lalu Anda akan menemukan semua periode yang tidak cocok.
Untuk contoh NOT IN LIST terakhir Anda, Anda dapat melihat bahwa itu cocok dengan dua aturan tersebut.
Anda harus memutuskan apakah periode-periode berikut ini DI DALAM atau DI LUAR rentang Anda:
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
Jika tabel Anda memiliki kolom yang disebut range_end dan range_start, berikut ini beberapa SQL sederhana untuk mengambil semua baris yang cocok:
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
Perhatikan TIDAK di sana. Karena dua aturan sederhana menemukan semua baris yang tidak cocok , NOT sederhana akan membalikkannya untuk mengatakan: jika bukan salah satu baris yang tidak cocok, itu harus salah satu baris yang cocok .
Menerapkan logika pembalikan sederhana di sini untuk menghilangkan NOT dan Anda akan berakhir dengan:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start