如何从日期时间列中选择日期?


238

我有一个类型为“ datetime”的列,其值类似于2009-10-20 10:00:00

我想从datetime提取日期并编写一个查询,例如:

SELECT * FROM 
data 
WHERE datetime = '2009-10-20' 
ORDER BY datetime DESC

以下是最好的方法吗?

SELECT * FROM 
data 
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC

但是,这将返回一个空的结果集。有什么建议?

Answers:


456

您可以使用MySQL的DATE()功能:

WHERE DATE(datetime) = '2009-10-20'

您也可以尝试以下方法:

WHERE datetime LIKE '2009-10-20%'

有关使用的性能影响的信息,请参见此答案LIKE


2
尝试过这个:DATE(datetime)='2009-10-20',它有效
mysqllearner

44
第一个非常慢,并且会忽略索引。最好设置'date%'
kachar

在哪里DATE(datetime)喜欢'%keyword%'它的工作,谢谢
silvia zulinka

2
我相信如果Rails时区不是UTC时,这将无法按预期工作。这是因为DATE()将列值解析为UTC。因此,找不到希望查询“ 2016-12-30”的日期,例如“星期五,2016年12月30日00:00:00 SGT +08:00”。为什么?因为DATE()会在进行比较之前将其解析为等效的UTC,即“ 2016-12-29 16:00:00 UTC”。如果我错了,请纠正我,因为直到最近我还是对我有所了解。
Tikiboy'1

WHERE DATE(datetime)='{?sdate}非常适合Crystal Reports参数!干得好!
MikeMighty

94

使用WHERE DATE(datetime) = '2009-10-20' 存在性能问题。如前所述这里

  • 它将计算DATE()所有行,包括不匹配的行。
  • 它将不可能使用索引进行查询。

使用BETWEEN><=运营商允许使用一个索引:

SELECT * FROM data 
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'

更新:LIKE索引列中使用而不是运算符的影响很大。这些是对包含1,176,000行的表的一些测试结果:

  • 使用datetime LIKE '2009-10-20%'=> 2931ms
  • 使用datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168ms

当对同一查询进行第二次调用时,差异甚至更大:2984ms vs 7ms(是的,只有7毫秒!)。我在使用Hibernate重写项目上的一些旧代码时发现了这一点。


有趣的是,如果MySql实现自动转换DATE(datetime)BETWEEN AND behine场景,我们将获得简短的陈述和出色的性能。为什么不?他们为什么不这样做?:)
樱桃

因为类似的东西DATE(datetime) in (:list)不起作用BETWEEN
Tim

25

您可以将日期时间格式化为YMD部分:

DATE_FORMAT(datetime, '%Y-%m-%d')

2
这样,您就可以在需要时仅获取时间部分:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

这可以很好地格式化日期时间,但作为回报,数据库将返回一个新数组以为其设置名称,只是在DATE_FORMAT(columnName,'%Y-%m-%d')arrayName末尾添加所需的名称以了解更多详细信息单证dev.mysql.com/doc/refman/8.0/en/...
里达·Rezzag

15

尽管页面上的所有答案都将返回期望的结果,但是它们都存在性能问题。切勿对子WHERE句中的字段执行计算(包括DATE()计算),因为必须对表中的所有行执行计算。

BETWEEN ... AND构造包含两种边界条件,要求在结束日期指定23:59:59语法,该语法本身还有其他问题(微秒事务,我相信MySQL在2009年提出问题时不支持)。

查询timestamp特定日期的MySQL 字段的正确方法是对照所需日期检查大于等于,然后在第二天检查小于等于(未指定小时)。

WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'

这是性能最快,内存最少,资源最少的方法,并且还支持所有MySQL功能和特殊情况,例如亚秒级时间戳精度。此外,这是未来的证明。


1
而且,使用性能参数,是在表的每一行上均等地计算了“> =”和“ <”,还是“神奇地”知道SQL数字是否大于另一个的SQL Server?:-)
哈维尔·格雷罗

@JavierGuerrero:我的示例比较了两个常量:表中的一个常量和字符串文字。
dotancohen

“表中的一个”不是常数,它对于每一行都是不同的,因此必须对每一行进行相同的计算(并且必须将两者都转换为纪元时间才能进行比较)
Javier Guerrero

9

这是所有格式

说这是包含datetime值table 的列data

+--------------------+
| date_created       |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+

mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02         |
+--------------------+

mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
|               2018 |
+--------------------+

mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
|                   6 |
+---------------------+

mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
|                 2 |
+-------------------+

mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
|                 15 |
+--------------------+

mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
|                   50 |
+----------------------+

mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
|                   31 |
+----------------------+

5

您可以使用:

DATEDIFF ( day , startdate , enddate ) = 0

要么:

DATEPART( day, startdate ) = DATEPART(day, enddate)
AND 
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)

要么:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))

5

简单,最佳的日期功能使用方法

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

要么

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'

-5

好吧, 在这种情况下使用LIKEin语句是最好的选择 WHERE datetime LIKE '2009-10-20%'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.