MySQL查询某些日期范围

时间:2013-09-03 23:59:49

标签: mysql date

我有以下表格数据:

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进行查询,但它接缝我需要构建几个案例 - 还是有更简单的方法? thankx

3 个答案:

答案 0 :(得分:12)

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

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

这是我们搜索的范围:

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

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

搜索应该给我们一个积极的结果,因为它们相交。但是,如果您使用其他答案,则会得到否定结果,因为start_dateend_date都不在start_searchend_search之间。

要获得解决方案,让我们绘制交叉点的所有4种可能模式

                  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

您可以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 */

一个不太直接的解决方案是:

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 */

尝试使用上面的图表将其可视化。

<小时/> 如果我们尝试从上面的4个图中推断出一个模式,我们可以看到在交叉点期间,end_date总是>= start_search,而另一方面,start_date总是{{} 1}}。事实上,进一步可视化,我们可以看到当这两个条件成立时,我们不能没有交叉点

因此,另一种解决方案就像:

<= end_search

此解决方案的优点是我们只需要进行2次比较。与&#34; select*from table where end_date >= start_search && start_date <= end_search 一切&#34;形成鲜明对比。方法需要2到8(3 + 3 + 2)个比较。 (每个OR调用都包含3 comparisons。)

答案 1 :(得分:7)

尝试:

SELECT *
FROM `Seasons`
WHERE (`from` BETWEEN '2013-09-04' AND '2013-09-05' OR `to` BETWEEN '2013-09-04' AND '2013-09-05')

答案 2 :(得分: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)