To niesamowite, że nikt tego nie zauważył od prawie dwóch lat, ale wszystkie pozostałe odpowiedzi są błędne ponieważ nie wzięli pod uwagę sytuacji, w której zarówno data rozpoczęcia, jak i data zakończenia wykraczają poza zakres wyszukiwania. Rozważmy, że jest to zakres dat:
start_date <<---------------------------- date range --------------------------->> end_date
A oto zakres naszych poszukiwań:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
Poszukiwania powinny dać nam pozytywny wynik, ponieważ się przecinają. Ale jeśli użyjesz innych odpowiedzi, otrzymasz wynik negatywny, ponieważ ani start_date
ani end_date
jest między start_search
i end_search
.
Aby uzyskać rozwiązanie, narysujmy wszystkie 4 możliwe tryby skrzyżowania:
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
Możesz OR
wszystkie 4 możliwe przypadki, aby uzyskać proste rozwiązanie:
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 */
Mniej proste rozwiązanie to:
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 */
Spróbuj to zwizualizować za pomocą powyższych diagramów.
Jeśli spróbujemy ekstrapolować wzorzec z 4 powyższych diagramów, zobaczymy, że podczas skrzyżowaniaend_date
to zawsze >= start_search
, a z drugiej strony start_date
to zawsze <= end_search
. Rzeczywiście, wizualizując dalej, widzimy, że kiedy te dwa warunki są spełnione, nie możemy nie mieć skrzyżowania . W związku z tym inne rozwiązanie jest tak proste, jak:
select*from table where
end_date >= start_search && start_date <= end_search
A zaletą tego rozwiązania jest to, że potrzebujemy tylko 2 porównań. Porównaj to z „OR
podejście „wszystko”, które wymaga od 2 do nawet 8 (3 + 3 + 2) porównań. (Każde between
rozmowa składa się z 3 porównań
.)