我想根据我给定的日期格式YYYY,MM,dd从数据库中检索记录,但列类型为YYYY,MM,dd hh:mm:ss。
试图使用日期格式功能
SELECT *
FROM tabl.error_logs
where created_at = DATE_FORMAT(NOW(),'%Y-%m-%d'- INTERVAL 3 DAY);
我希望创建日期为2019-06-08,但结果为空
答案 0 :(得分:1)
要进行查询sargable,您需要...
SELECT *
FROM tabl.error_logs
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 3 DAY)
AND created_at < DATE_SUB(CURDATE(), INTERVAL 2 DAY)
这会选择三天前午夜或之后的created_at
的所有值,直到但不包括两天前午夜的<
。如果有索引,它将对created_at
上的索引使用范围扫描。
答案 1 :(得分:1)
created_at
列的实际数据类型是什么?
此答案将忽略带有逗号格式的时髦性,并假定它不是字符类型数据,而是DATETIME
或TIMESTAMP
。
DATETIME
和TIMESTAMP
列上谓词的规范模式是范围比较。
例如,要获取6月10日的所有datetimecol值,则如下所示:
WHERE t.datetimecol >= '2019-06-10 00:00:00'
AND t.datetimecol < '2019-06-11 00:00:00'
通常,我只传递那个日期值,然后让MySQL找出第二天。如果我们省略时间部分,MySQL将假设00:00:00
WHERE t.datetimecol >= '2019-06-10' + INTERVAL 0 DAY
AND t.datetimecol < '2019-06-10' + INTERVAL 1 DAY
为了提高性能,为了允许MySQL有效地在适当的索引上使用范围扫描操作,我们希望避免将列引用包装在函数中。也就是说,在WHERE子句的条件中指定DATE(t.datetimecol)
将迫使MySQL在表的每一行上评估DATE()
函数。
通过引用裸列,如果合适的索引可用,则允许MySQL使用索引。
例如
SELECT e.*
FROM tabl.error_logs e
WHERE e.created_at >= DATE(NOW()) + INTERVAL -3 DAY
AND e.created_at < DATE(NOW()) + INTERVAL -2 DAY
请注意,我们可以轻松地在WHERE子句中测试这些表达式,以验证它们是否返回了我们想要的内容,并根据需要进行调整:
SELECT DATE(NOW()) + INTERVAL -3 DAY
, DATE(NOW()) + INTERVAL -2 DAY
答案 2 :(得分:0)
您可以使用date_sub()
SELECT *
FROM tabl.error_logs
where date(created_at) = DATE_SUB(date(now()), INTERVAL 3 DAY);
如果created_at列是一个日期,则可以避免使用date()函数,并让该列的索引(如果存在)起作用
SELECT *
FROM tabl.error_logs
where created_at = DATE_SUB(date(now()), INTERVAL 3 DAY);