【问题标题】:Invalid result when 2 dates (String) are compared比较 2 个日期(字符串)时结果无效
【发布时间】:2023-03-28 12:41:01
【问题描述】:

我的 MySQL 数据库中有一个名为 test 的表。下面是它的创建方式。

CREATE TABLE `test` (
 `update_date` varchar(10) NOT NULL,
 `value` double NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

下面是它的数据。

我按照here的选定答​​案中的描述运行以下查询

SELECT SUM(`value`) FROM `test`
WHERE STR_TO_DATE(`update_date`, '%d-%m-%Y') BETWEEN '01-10-2014' AND '31-10-2014'

这应该返回 1800,但它却返回了 NULL。为什么会这样?如何才能得到正确答案?

非常重要:我必须将String 用于Date,因为我必须以dd-mm-yyyy 格式保存日期,而mysql Date 不接受它。

【问题讨论】:

  • Mysql date 不会以任何特定格式存储日期。事实上,日期通常存储为相对于基准日期的偏移量(十进制值)。不要使用字符串来存储日期,使用日期。如何显示或比较日期取决于您,但始终从字符串转换为日期会影响性能
  • 查看文档表明 DATE 存储为 3 个字节。尽管他们说数据是在 YYYY-MM-DD 中检索和显示的,但这些文档会误导新手。这并不意味着它以这种格式存储。不要使用字符串,在查询中转换日期。想一想 - 需要一个函数调用来转换日期参数,但需要一个函数调用 PER ROW 来将表中的数据从字符串转换为日期。此外,由于应用于列的标量而不会使用索引,并且您要求性能不佳
  • 只是为了证明不是春季日期作为字符串en.m.wikipedia.org/wiki/Sargable
  • @Charleh: 你的意思是Date 对象可以保存在dd-mm-yyyy 中?我经历了很多问题、帖子和示例,都说不是。
  • 它不以任何格式保存 - 它保存为一系列位(3 个字节,即 24 位,例如000010100011100101011010),这可能表示与过去某个点的偏移量。您在 MySQL 中以YYYY-MM-DD 格式检索日期,但如何显示它们取决于您的应用程序层,而不是数据库层。如果您使用数据库层来格式化日期,那么您通常做错了。如果您将日期存储为字符串,则会影响性能,因为转换日期字符串与比较存储日期的 24 位相比成本很高。在您的应用程序中格式化日期而不是您的 SQL

标签: mysql sql date varchar str-to-date


【解决方案1】:

试试这个:

 SELECT SUM(`value`) FROM `test`
 WHERE STR_TO_DATE(`update_date`, '%d-%m-%Y') 
 BETWEEN STR_TO_DATE('01-10-2014', '%d-%m-%Y') AND STR_TO_DATE('31-10-2014', '%d-%m-%Y')

或者你也可以这样做:

SELECT SUM(`value`) FROM `test`
WHERE STR_TO_DATE(`update_date`, '%d-%m-%Y') 
BETWEEN '2014-10-01' AND '2014-10-31'  -- in Y-m-d

两个查询都应返回 1800

注意STR_TO_DATE() 返回DATETIME 值,其格式为Y-m-d

【讨论】:

    猜你喜欢
    • 2020-11-14
    • 1970-01-01
    • 2013-12-09
    • 2019-07-25
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多