Thật ngạc nhiên là không ai nhận ra điều này trong gần hai năm, nhưng các câu trả lời khác đều sai bởi vì họ đã không tính đến trường hợp cả ngày bắt đầu và ngày kết thúc đều nằm ngoài phạm vi phạm vi tìm kiếm. Hãy coi đây là phạm vi ngày:
start_date <<---------------------------- date range --------------------------->> end_date
Và đây là phạm vi tìm kiếm của chúng tôi:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
Việc tìm kiếm sẽ cho chúng ta một kết quả tích cực vì chúng giao nhau. Nhưng nếu bạn sử dụng các câu trả lời khác, bạn sẽ nhận được kết quả âm vì cả start_date
cũng không phải end_date
nằm giữa start_search
và end_search
.
Để có giải pháp, hãy vẽ tất cả 4 chế độ có thể có giao lộ:
start_date <<---------- date range --------------------------->> end_date start_search <<------------------------- search range -------->> end_search
start_date <<---------------------------- date range ---------->> end_date start_search <<---------- search range ------------------------>> end_search
start_date <<---------------------------- date range --------------------------->> end_date start_search <<-------- search range -------->> end_search
start_date <<----------- date range -------->> end_date start_search <<------------------------- search range ------------------------>> end_search
Bạn có thể OR
cả 4 trường hợp có thể xảy ra để có được giải pháp đơn giản:
select*from table where
/* 1st case */ start_date between start_search and end_search
or /* 2nd case */ end_date between start_search and end_search
or /* 3rd case */ (start_date <= start_search and end_date >= end_search)
or /* 4th case */ (start_date >= start_search and end_date <= end_search)
/* the 4th case here is actually redundant since it is being covered by the 1st and 2nd cases */
Một giải pháp ít đơn giản hơn là:
select*from table where start_date between start_search and end_search /* covers 1st and 4th cases */ or start_search between start_date and end_date /* covers 2nd and 3rd cases */
Hãy thử hình dung nó bằng cách sử dụng các sơ đồ trên.
Nếu chúng ta cố gắng ngoại suy một mẫu trong số 4 sơ đồ ở trên, chúng ta có thể thấy rằng trong một giao lộ,end_date
luôn là >= start_search
và mặt khác, start_date
luôn là <= end_search
. Thật vậy, hình dung sâu hơn, chúng ta có thể thấy rằng khi hai điều kiện đó giữ nguyên, chúng ta không thể không có giao điểm . Như vậy, một giải pháp khác cũng đơn giản như:
select*from table where
end_date >= start_search && start_date <= end_search
Và ưu điểm của giải pháp này là chúng ta chỉ cần 2 phép so sánh. Ngược lại với "OR
mọi thứ "phương pháp tiếp cận yêu cầu từ 2 đến tối đa 8 (3 &cộng; 3 &cộng; 2) so sánh. (Mỗi between
cuộc gọi bao gồm 3 phép so sánh
.)