【问题标题】:Using mysql to query dates that fall between 2 other dates使用 mysql 查询介于 2 个其他日期之间的日期
【发布时间】:2013-07-17 06:35:57
【问题描述】:

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

【问题讨论】:

  • 您能否更清楚地了解您需要什么,在整个 30 天内处于活动状态的项目或在 30 天内处于活动状态的所有项目(无论持续时间长短)?

标签: mysql


【解决方案1】:

假设 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 天,具体取决于您如何定义“接下来的 30 天”。


问:在 NOW 之前开始并在接下来的 30 天内运行的项目会怎样?

答:我想我明白你在问什么。

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

现在,我将只考虑“ start_date

我们可以像这样(相当粗略地)描述可能的情况: 竖线代表 NOW 和 NOW+30 小于号表示“start_date” 大于号表示“end_date” 破折号表示 DATETIME 在 start_date 和 end_date 之间的范围

      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 部分,请将 NOW() 函数包装在 DATE() 函数中:

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

我搁置了 start_date > 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

【讨论】:

  • 那些在NOW 之前开始并且将在接下来的 30 天内运行的项目呢?
  • @koala_dev:好点。我添加了可能情况的粗略说明,并添加了应满足要求的谓词(WHERE 子句)。
  • +1 干得好@spencer7593。我认为您的更新正是 OP 解决他的问题所需要的。
猜你喜欢
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多