我有一个包含字段'start_date'和字段'end_date'的表。当前日期介于“start_date”和“end_date”之间时,项目被视为有效。如何找到在接下来的30天内被认为有效的所有项目。
答案 0 :(得分:3)
假设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天,具体取决于您定义的方式&#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