使用mysql查询介于2个其他日期之间的日期

时间:2013-07-16 20:38:14

标签: mysql

我有一个包含字段'start_date'和字段'end_date'的表。当前日期介于“start_date”和“end_date”之间时,项目被视为有效。如何找到在接下来的30天内被认为有效的所有项目。

1 个答案:

答案 0 :(得分:3)

假设start_dateend_date是DATETIME,并且您想要比较日期和时间组件,您可以执行以下操作:

<击>

<击>
SELECT a.*
  FROM atable a
 WHERE a.start_date >= NOW()
   AND a.end_date   <= NOW() + INTERVAL 30 DAYS

<击>

如果start_date和end_date是DATE(而不是DATETIME),您可能只想比较DATE部分(不考虑时间组件)

<击>

<击>
SELECT a.*
  FROM atable a
 WHERE a.start_date >= DATE(NOW())
   AND a.end_date   <= DATE(NOW()) + INTERVAL 30 DAYS

<击>

在结束日期,您实际上可能希望小于比较(而不是小于或等于)。您需要确定在边缘情况下您想要的结果。并且间隔可能需要指定为29天,具体取决于您定义的方式&#34;接下来的30天&#34;。


问:那些在NOW之前开始并将在接下来的30天内投放的商品呢?

A:我想我理解你在问什么。

我认为你想要检索start_date和end_date之间任何时间点之间的任何行,从现在到现在30天之间。我可以看到上面的查询没有回答这个问题。

目前,我只会考虑&#34; start_date&lt; end_date&#34;,并搁置start_date不小于end_date,或start_date或end_date或两者都为NULL的情况。

我们可以像这样描述可能的情况(相当粗略):      垂直条代表NOW和NOW + 30      小于号代表&#34; start_date&#34;      大于号表示&#34; end_date&#34;      破折号表示start_date和end_date

之间的DATETIME范围
      NOW     NOW+30
<--->  |       |              case 1: end_date < NOW()
   <---|---->  |              case 2: NOW() between start_date and end_date
    <--|-------|---->         case 3: NOW() > start_date and NOW+30 < end_date
       | <---> |              case 4: both start_date and end_date between NOW() and NOW()+30
       |    <--|--->          case 5: start_date between NOW() and NOW()+30 and end_date > NOW+30 
       |       |  <--->       case 6: start_date > NOW()+30


   <--->       |              case e1: end_date = NOW()
    <--|------->              case e2: start_date > NOW() AND end_date = NOW()+30
       <--->   |              case e3: start_date = NOW() and end_date < NOW()+30
       <------->              case e4: start_date = NOW() and end_date = NOW()+30
       <-------|-->           case e5: start_date = NOW() and end_date > NOW()+30
       |   <--->              case e6: start_date > NOW() AND end_date = NOW()+30
       |       <--->          case e7: start_date = NOW()+30

我认为您要求返回满足案例2到5的行,这是案例1和案例6的所有情况除外。

如果我们可以编写一个测试案例1和6的谓词,然后否定它,它应该给我们你想要的东西。像这样:

处理考虑了时间成分的日期时间:

  WHERE NOT ( end_date < NOW() OR start_date > NOW() + INTERVAL 30 DAYS )

如果start_date和end_date是DATE,只比较DATE部分,在DATE()函数中包装NOW()函数:

  WHERE NOT ( end_date < DATE(NOW()) OR start_date > DATE(NOW()) + INTERVAL 30 DAYS )

我搁置了start_date&gt;的古怪案例。 end_date,start_date = end_date,start_date IS NULL,end_date IS NULL等。我也省略了边缘情况(e1到e7)的讨论,例如, start_date = NOW(),end_date = NOW()等。为了完整起见,您可能想要检查是否使用相同的谓词正确处理了这些情况。


DOH!

我突然意识到这一点:

 WHERE NOT ( a < n OR b > t )

等同于此(至少对于非空值)

 WHERE ( a >= n AND b <= t )

所以这个谓词应该是等价的:

 WHERE end_date >= NOW() AND start_date <= NOW() + INTERVAL 30 DAYS