【问题标题】:MySQL compare DATE string with string from DATETIME fieldMySQL 将 DATE 字符串与 DATETIME 字段中的字符串进行比较
【发布时间】:2011-02-15 01:18:06
【问题描述】:

我有一个问题:是否可以通过将一个 DATE 字符串“2010-04-29”与存储为 DATETIME (2010-04-29 10:00) 的字符串进行比较来从 MySQL 数据库中进行选择?

我有一个过滤数据的日期选择器,我想通过 DATETIME 字段查询表,如下所示:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

...我想获取 DATETIME 值为“2010-04-29 10:00”的行。

有什么建议吗?谢谢。

【问题讨论】:

    标签: mysql datetime comparison


    【解决方案1】:

    您可以将 DATETIME 字段转换为 DATE:

    SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'
    

    这非常有效。

    【讨论】:

    • 不,它也没有效率。如果startTime 被编入索引,这将无法使用索引
    【解决方案2】:
    SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')
    

    这用于mysql中的日期时间格式,使用DATE_FORMAT(date,format)

    【讨论】:

    • 最好添加一些解释
    【解决方案3】:
    SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"
    

    SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
    

    【讨论】:

    • 这是一个糟糕的查询。不惜一切代价避免这种情况。如果 startTime 上有索引,则此查询无法使用它,因为它将函数应用于列而不是直接使用它。这意味着任何像这样的查询都需要全表扫描。在大表上,这意味着查询速度极慢。
    • 我同意,他的回答是错误 - 正确的答案是大卫在下面发布的。
    • 请使用大卫的答案,因为它更快。这个是有效的,但对速度不利...
    • @CarlosAlbertoMartínezGadea 这个版本很慢,因为它必须在比较之前将每个值格式化为字符串......大卫的版本不需要它,但仍然不能使用索引,所以不是最佳的。有关可以使用索引的版本,请参阅 XL_ 的答案。不幸的是,在 mysql 中没有更好的方法来正确地做到这一点
    • 我对这个答案投了反对票,因为查询不能使用索引,而 @XL_ 的答案可以。
    【解决方案4】:

    使用以下内容:

    SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
    

    仅供参考我有一个 200 万条记录的表,我运行了一个类似的查询。 Salils 的回答耗时 4.48 秒,上面的耗时 2.25 秒。

    所以如果桌子很大,我会建议这样做。

    【讨论】:

    • 第一个答案太慢了,因为它必须在比较之前将每个日期时间格式化为字符串。你的更好,因为它直接比较字段中的日期部分,但它仍然不能使用索引(在 mysql 5.1 上测试)
    • 如果性能是一个问题,可能值得考虑单独存储日期和时间部分,以便可以在日期部分放置一个索引。
    • 如果startTime 被索引,这个查询将不能使用索引。
    【解决方案5】:

    如果要选择 DATETIME 列的 DATE 部分与某个文字匹配的所有行,则不能这样做:

    WHERE startTime = '2010-04-29'
    

    因为 MySQL 不能直接比较 DATE 和 DATETIME。 MySQL 的作用是使用时间 '00:00:00' 扩展给定的 DATE 文字。所以你的条件变成了

    WHERE startTime = '2010-04-29 00:00:00'
    

    当然不是你想要的!

    条件是一个范围,因此它应该作为范围给出。有几种可能:

    WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
    WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)
    

    第一个错误的可能性很小 - 当您的 DATETIME 列使用亚秒级分辨率并且在 23:59:59 + epsilon 有约会时。一般来说,我建议使用第二种变体。

    两种变体都可以在 startTime 上使用索引,这将在表增长时变得重要。

    【讨论】:

    • 大卫的版本不好,不能使用索引。要使用索引,您必须直接过滤列,而不是函数的结果(date()year()datediff() 或任何类似的)
    • 我正在寻找 mysql 如何将日期转换为 datetime ,感谢您清除它添加了 00:00:00 。现在我的结果有意义
    • 与其他无法使用索引(如果可用)的答案相比,这是正确的快速解决方案
    【解决方案6】:
    SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'
    

    如果您想在 MySQL 日期之后或之前查找某些内容,也可以使用比较运算符。这是因为它们的编写方式(最大值到最小值,前导零)使得简单的字符串排序可以正确排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多