我有一些带有datetime列的表,我想从中获取所有结果:
如果我在2016-01-28 11:12:24
上执行查询,我想从整整一个小时(11:00:00
)获取3天前的所有结果。因此,我会获得2016-01-28 11:00:00
和2016-01-28 11:59:59
之间的所有行。我如何做到这一点,以便我可以在此日期时间列上受益于索引?
我尝试过使用WHERE DATE_FORMAT(o.created_at, '%Y-%m-%d %H:00:00') = DATE_FORMAT(NOW() INTERVAL -3 DAY, '%Y-%m-%d %H:00:00')
,但它是一个函数,因此查询不会使用索引。
答案 0 :(得分:1)
最好的解决方案是:
WHERE o.created_at >= DATE_FORMAT(date_sub(now(), interval 3 day), '%Y-%m-%d %H:00:00') AND o.created_at < DATE_FORMAT(date_add(date_sub(now(), interval 3 day), interval 1 hour), '%Y-%m-%d %H:00:00')
或者,你也可以这样做,但只能精确到秒:
WHERE o.created_at BETWEEN DATE_FORMAT(date_sub(now(), interval 3 day), '%Y-%m-%d %H:00:00') AND DATE_FORMAT(date_sub(now(), interval 3 day), '%Y-%m-%d %H:59:59')
此处的BETWEEN AND
子句仍使用索引,因为我们尚未在列DATE_FORMAT
上使用o.created_at
函数。如果所选数据小于总行数的1/3,则效率也更高。
[参考:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html]
注意:感谢@Used_By_Already指出问题的精确度高达微秒。
答案 1 :(得分:0)
不要使用NOW() Interval - 3....
格式化新日期,而是查看DateDiff()
。这允许您设置从NOW()
到其他日期的差异并设置度量单位。