นี่เป็นปัญหาคลาสสิกและง่ายกว่าถ้าคุณย้อนกลับตรรกะ
ผมขอยกตัวอย่าง
ฉันจะโพสต์ช่วงเวลาหนึ่งไว้ที่นี่และรูปแบบต่างๆของช่วงเวลาอื่น ๆ ที่ทับซ้อนกันในบางลักษณะ
|-------------------| 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)
สังเกตสิ่งที่ไม่อยู่ในนั้น เนื่องจากทั้งสองกฎง่ายๆพบว่าทั้งหมดไม่ตรงแถวที่เรียบง่ายไม่ได้จะกลับมันจะพูดว่า: ถ้ามันไม่ได้เป็นหนึ่งในแถวที่ไม่ตรงกันก็จะต้องมีคนหนึ่งที่ตรงกัน
ใช้ตรรกะการย้อนกลับอย่างง่ายที่นี่เพื่อกำจัด NOT และคุณจะได้รับ:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start