【问题标题】:Mysql: No results on query after STR_TO_DATE conversionMysql:STR_TO_DATE 转换后查询没有结果
【发布时间】:2020-08-08 21:26:22
【问题描述】:

我有一个表格,其中一列上有字符串,字符串的格式是 ISO 8601(带 TZ)。

当我尝试运行以下查询时:

select * from `orders` where STR_TO_DATE('last_ship_date', '%Y-%m-%dT%TZ') >= STR_TO_DATE('2020-06-27 21:13:14', '%Y-%m-%d %h:%i:%s')

我没有结果,即使我在:“last_ship_date”列中具有相同格式和范围的日期(6 月 27 日之后),例如:2020-08-09T06:59:59Z

我在这里缺少什么?为什么 STR_TO_DATE 转换后无法选择行?

谢谢。

【问题讨论】:

  • 如果日期存储为 ISO 8601,您可以在不调用 STR_TO_DATE() 的情况下进行比较。

标签: mysql sql phpmyadmin query-optimization where-clause


【解决方案1】:

您的代码存在 2 个问题:

(1) last_ship_date 列用单引号括起来,因此它被视为字符串文字而不是列名

(2) 在第二个日期的格式中,您必须使用 %H 而不是 %h,因为您列中的小时是 24 小时格式。

所以改成这样:

select * from `orders` 
where STR_TO_DATE(last_ship_date, '%Y-%m-%dT%TZ') >= 
      STR_TO_DATE('2020-06-27 21:13:14', '%Y-%m-%d %H:%i:%s')

但您也可以简化为:

select * from `orders` 
where STR_TO_DATE(last_ship_date, '%Y-%m-%dT%TZ') >= '2020-06-27 21:13:14'

【讨论】:

    【解决方案2】:

    您的首要工作应该是修复您的数据模型,并将日期存储为日期而不是字符串。使用正确的数据类型,您甚至不会遇到这个问题。

    也就是说:不对您过滤的列应用函数总是更快。您的字符串日期具有可用于比较和排序的格式,因此您宁愿将参数转换为目标格式:

    select * 
    from `orders`
    where last_ship_date = DATE_FORMAT('2020-06-27 21:13:14', '%Y-%m-%dT%H:%i:%sZ')
    

    此谓词将利用last_ship_date 上的索引。

    【讨论】:

    • 我完全同意,它是一个生产中的站点,我们将在下一个版本中修复它,现在我们必须在不更改数据模型的情况下进行修复,谢谢!
    【解决方案3】:

    ISO 8601 日期/时间格式的优点之一是可以按字典顺序进行比较。所以一开始就没有必要打电话给STR_TO_DATE()。只需将T 分隔符和Z 区域添加到要与之比较的字符串即可。

    select * from `orders` 
    where last_ship_date' >= '2020-06-27T21:13:14Z'
    

    【讨论】:

    • 你说得对,你只能把它当作一个字符串来比较!谢谢
    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 2013-11-30
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多