Удивително е, че никой не е забелязал това от почти две години, но другите отговори са грешни защото не са взели предвид случая, когато и началната, и крайната дата попадат извън обхвата на диапазона на търсене. Помислете, че това е диапазонът на датата:
start_date <<---------------------------- date range --------------------------->> end_date
И това е диапазонът на нашето търсене:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
Търсенето трябва да ни даде положителен резултат, защото се пресичат. Но ако използвате другите отговори, ще получите отрицателен резултат, защото нито start_date
нито end_date
е между start_search
и end_search
.
За да получите решението, нека нарисуваме всичките 4 възможни режима на пресичане:
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
Можете да OR
всичките 4 възможни случая за получаване на простото решение:
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 */
По-малко просто решение е:
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 */
Опитайте се да го визуализирате с помощта на диаграмите по-горе.
Ако се опитаме да екстраполираме модел от 4-те диаграми по-горе, можем да видим, че по време на пресичане,end_date
винаги е >= start_search
, а от другата страна start_date
винаги е <= end_search
. Всъщност, визуализирайки по-нататък, можем да видим, че когато тези две условия са изпълнени, не можем да нямаме кръстовище . Като такова, друго решение е толкова просто като:
select*from table where
end_date >= start_search && start_date <= end_search
И предимството на това решение е, че имаме нужда само от 2 сравнения. Сравнете това с „OR
всичко", който изисква от 2 до 8 (3 + 3 + 2) сравнения. (Всяко between
обаждането се състои от 3 сравнения
.)