【问题标题】:Operators on date/time fields日期/时间字段的运算符
【发布时间】:2021-04-08 15:59:09
【问题描述】:

+- 运算符是在标准 sql 中定义的日期/时间类型,例如时间、持续时间、日期、日期时间、时间戳。这是 MySQL 的一个例子:

select 
date '1983-09-05', time '01:02:03', timestamp '2014-01-01 01:02:03',
date '1983-09-05' + time '01:02:03', timestamp '1983-09-05 01:02:03' + time '01:02:03'

似乎最后三个结果只是胡言乱语(就实际给出有意义的结果而言)。是否有关于时间类型应该如何加减的标准,或者它是未定义的行为,建议使用函数来处理这种东西?

【问题讨论】:

  • 据我所知,SQL 标准仅定义了操作 timestamp +/- intervaltimestamp - timestamp,但没有定义例如date + timetimestamp + time。例如,Postgres 支持date + time,它只会产生timestamp,但不支持timestamp + time(无论如何这都没有意义)。但timestamp + interval 显然是。由于 MySQL 的“时间”类型本质上是伪装的 interval(因为它允许超过 24 小时),也许这就是它接受语法的原因
  • @a_horse_with_no_name 谢谢。我认为timestamp + time 可以,不是吗?如果是周五下午 2 点,而您想知道从现在起 3 小时后是什么时间呢?我正在非正式地写它,但这会转化为时间戳+时间/持续时间,对吗?
  • “3 小时后”是interval,所以你需要timestamp + interval。正如我已经写过的:MySQL 的“时间”数据类型实际上并不是 SQL 标准定义的 time 类型,它代表“一天中的时间”,例如“早上 8 点”或“午夜半点”。 MySQL 的“时间”类型更接近于 SQL 标准中定义为 interval hours to minute 的内容。
  • 我想知道为什么知道或思考这些深奥的东西会有用
  • @MartinSmith:我知道 MySQL 接受它。但这没有任何意义——至少对我和(显然也不是 David542)。不过 Postgres 做了正确的事情:dbfiddle.uk/…(我不得不承认我 am 很惊讶 timestamp + time 确实有效)

标签: mysql sql ansi-sql


【解决方案1】:

MySQL 不会产生乱码。它只是变得混乱。问题是 MySQL 试图弄清楚你的意思:

  • + 真的是用于数字加法还是用于日期/时间?
  • 常量真的是字符串、日期/时间还是数字?

MySQL 为这些(可能)违反直觉的选择做出了选择。例如,'2014-01-01 01:02:03' 等日期/时间值将转换为类似于20140101010203 的数字。这种转换在某些情况下会隐式发生。

让我用日期来说明这一点。你可能认为这些是等价的:

select '2021-01-01' + 40,
       date '2021-01-01' + 40,
       '2021-01-01' + interval 40 day

结果是:

2061    20210141    2021-02-10

发生了什么?首先,+ 被视为一个数字加法。第一个参数被转换为一个数字——即前导数字直到第一个非数字。

在第二个中,+ 也被视为数字加法。日期被转换为一个数字,看起来像 20,210,101 - 即 YYYYMMDD 作为一个整数

最后,第三个告诉 MySQL 做你想做的事——加 40 天。

这与标准 SQL无关,标准 SQL 明确定义了加减间隔和时间戳的差异。这些只是 MySQL 用于消除 +- 歧义以及将日期/时间转换为数字的规则。

【讨论】:

  • 一如既往地感谢您。一个问题:standard SQL, which clearly defines adding and subtracting intervals and the difference of timestamps——它是否提到了需要完成的“如何”——例如使用运算符或函数?或者它只是说需要做,由供应商决定如何做?
  • @David542 。 . .是的。该标准将+/- 指定为这些操作支持的运算符。
猜你喜欢
  • 2023-01-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-29
  • 1970-01-01
相关资源
最近更新 更多