7

我有下表数据:

Table: Seasons                
id   from        to
---------------------------
1    2013-08-30  2013-09-04
2    2013-09-05  2013-09-08
3    2013-09-09  2013-09-20

我需要运行一个查询,该查询返回某个日期范围内的所有记录,例如:返回所有受影响的记录2013-09-04 to 2013-09-05

就像

date  range:                    | 09-04 - 09-05| 
seasons:          08-30 - 09-04 | 09-05 - 09-08     | 09-09 - 09-20

所以它应该返回前 2 条记录。我已经尝试使用 BETWEEN 进行查询,但它接缝我需要建立几个案例 - 还是有更简单的方法?谢谢

4

3 回答 3

15

令人惊讶的是,近两年没有人注意到这一点,但其他答案都是错误的,因为他们没有考虑开始日期和结束日期都超出搜索范围的情况。考虑这是日期的范围:

start_date <<---------------------------- date range --------------------------->> end_date

这是我们的搜索范围:

start_date <<---------------------------- date range --------------------------->> end_date

                 start_search <<-------- search range -------->> end_search

搜索应该给我们一个积极的结果,因为它们相交。但是如果你使用其他答案,你会得到一个否定的结果,因为两者start_date都不end_datestart_searchand之间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 个比较。)

于 2015-03-02T04:59:01.407 回答
8

尝试:

SELECT *
FROM `Seasons`
WHERE (`from` BETWEEN '2013-09-04' AND '2013-09-05' OR `to` BETWEEN '2013-09-04' AND '2013-09-05')
于 2013-09-04T02:08:47.090 回答
2

这应该工作

SELECT *
FROM `Seasons`
WHERE (date_field BETWEEN '2010-01-30 14:15:55' AND '2010-09-29 10:15:55')

**确保日期为 mysql 默认格式 (yyyy-mm-ff hh:mm:ss)

于 2013-09-04T00:04:37.910 回答