Det är fantastiskt att ingen har lagt märke till detta på nästan två år, men de andra svaren är alla fel eftersom de inte tog hänsyn till fallet när både startdatum och slutdatum faller utanför räckvidden för sökintervallet. Tänk på att detta är datumintervallet:
start_date <<---------------------------- date range --------------------------->> end_date
Och detta är omfattningen av vår sökning:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
Sökningen bör ge oss ett positivt resultat eftersom de skär varandra. Men om du använder de andra svaren skulle du få ett negativt resultat eftersom varken start_date
inte heller end_date
är mellan start_search
och end_search
.
För att få lösningen, låt oss rita alla fyra möjliga lägen av korsningen:
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
Du kan OR
alla 4 möjliga fall för att få den enkla lösningen:
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 */
En mindre enkel lösning är:
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 */
Försök att visualisera det med hjälp av diagrammen ovan.
Om vi försöker extrapolera ett mönster av de fyra diagrammen ovan kan vi se att under en korsning,end_date
är alltid >= start_search
, och på baksidan, start_date
är alltid <= end_search
. När vi visualiserar ytterligare kan vi se att när dessa två villkor gäller kan vi inte ha en korsning . Som sådan är en annan lösning så enkel som:
select*from table where
end_date >= start_search && start_date <= end_search
Och fördelen med denna lösning är att vi bara behöver 2 jämförelser. Jämför det med "OR
allt"-metoden som kräver från 2 upp till så mycket som 8 (3 + 3 + 2) jämförelser. (Varje between
samtalet består av 3 jämförelser
.)