我有一个表,其中包含一个字段“start_date”和一个字段“end_date”。当当前日期在“start_date”和“end_date”之间时,项目被认为是活动的。我如何找到在接下来的 30 天内被视为处于活动状态的所有项目。
1 回答
假设start_date
和end_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 天内运行的项目呢?
A:我想我明白你在问什么。
我认为您想要检索 start_date 和 end_date 之间的任何时间点从现在到 30 天之间的任何时间点的任何行。我可以看到我上面的查询没有回答这个问题。
现在,我将只考虑“ start_date < end_date ”的情况,以及 start_date 不小于 end_date 或 start_date 或 end_date 或两者都为 NULL 的情况。
我们可以像这样(相当粗略地)描述可能的情况: 竖线表示 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( ) 等。为了完整起见,您可能需要检查这些情况是否使用相同的谓词进行了适当的处理。
哦!
我突然意识到:
WHERE NOT ( a < n OR b > t )
相当于这个(至少对于非空值)
WHERE ( a >= n AND b <= t )
所以这个谓词应该是等价的:
WHERE end_date >= NOW() AND start_date <= NOW() + INTERVAL 30 DAYS