É incrível que ninguém tenha notado isso por quase dois anos, mas as outras respostas estão todas erradas porque eles não levaram em consideração o caso em que a data de início e a data de término estão além do escopo do intervalo de pesquisa. Considere que este é o intervalo da data:
start_date <<---------------------------- date range --------------------------->> end_date
E este é o alcance da nossa pesquisa:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
A pesquisa deve nos dar um resultado positivo porque eles se cruzam. Mas se você usar as outras respostas, obterá um resultado negativo porque nem
start_date
nem end_date
está entre start_search
e end_search
. Para obter a solução, vamos desenhar todos os 4 modos possíveis de cruzamento:
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
Você pode
OR
todos os 4 casos possíveis para obter a solução direta: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 */
Uma solução menos direta é:
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 */
Tente visualizá-lo usando os diagramas acima.
Se tentarmos extrapolar um padrão dos 4 diagramas acima, podemos ver que durante uma interseção,
end_date
é sempre >= start_search
, e por outro lado, start_date
é sempre <= end_search
. De fato, visualizando mais, podemos ver que quando essas duas condições são válidas, não podemos deixar de ter uma interseção . Como tal, outra solução é tão simples quanto:
select*from table where
end_date >= start_search && start_date <= end_search
E a vantagem desta solução é que só precisamos de 2 comparações. Compare isso com o "
OR
tudo" que requer de 2 até 8 (3 + 3 + 2) comparações. (Cada between
chamada consiste em 3 comparações
.)