令人惊讶的是,近两年没有人注意到这一点,但其他答案都是错误的,因为他们没有考虑开始日期和结束日期都超出的情况搜索范围的范围。考虑这是日期的范围:
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 > end_date
start_search > end_search
start_date > end_date
start_search > end_search
start_date > end_date
start_search > end_search
start_date > end_date
start_search > 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 */
一个不太直接的解决方案是:
从表中选择*
start_search 和 end_search 之间的 start_date /* 涵盖第 1 和第 4 种情况 */
或 start_search 在 start_date 和 end_date 之间 /* 涵盖第 2 和第 3 种情况 */
尝试使用上面的图表将其可视化。
如果我们尝试从上面的 4 个图表中推断出一个模式,我们可以看到在交叉路口,
end_date 始终是
>= start_search,而另一方面,
start_date 始终是
<= end_search。事实上,进一步可视化,我们可以看到
当这两个条件成立时,我们不可能没有交集。
因此,另一种解决方案很简单:
select*from table where
end_date >= start_search && start_date <= end_search
而且这个解决方案的优点是我们只需要 2 次比较。相比之下,“OR Everything”方法需要 2 到多达 8 次(3 + 3 + 2)比较。 (每个between 调用都包含3 comparisons。)