令人惊讶的是,近两年没有人注意到这一点,但其他答案都是错误的,因为他们没有考虑开始日期和结束日期都超出搜索范围的情况。考虑这是日期的范围:
start_date <<---------------------------- date range --------------------------->> end_date
这是我们的搜索范围:
start_date <<---------------------------- date range --------------------------->> end_date
start_search <<-------- search range -------->> end_search
搜索应该给我们一个积极的结果,因为它们相交。但是如果你使用其他答案,你会得到一个否定的结果,因为两者start_date
都不end_date
在start_search
and之间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_date 和 end_date 之间的start_search /* 涵盖第 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
与需要 2 到多达 8 (3 + 3 + 2) 次比较的“一切”方法形成对比。(每个between
调用包含3 个比较。)