mysql - mariadb/mysql NOW() 和 TIMESTAMPDIFF 行为 - 是设计使然吗?

标签 mysql timestamp mariadb sysdate timestampdiff

只是将一些代码从 OracleDB 移植到 MariaDB 中,并将一些 OracleDB 表达式(例如 SYSDATE - ?/1440)转换为 MariaDB 表示法(这似乎很合适:NOW() - 间隔60 * ? 秒)。

在调试以下行为不当的表达式时(基本上比较 2 个历史“锁定”的持续时间),偶然发现了我怀疑是已知错误或已记录的行为(请帮助)

WHERE (a.expirationDt - a.acquisitionDt) > (b.expirationDt - b.acquisitionDt)

在 OracleDB 中 - 这个表达式一致/可靠地工作。 在MariaDB中 - 它似乎取决于减去的时间戳是否属于同一分钟(然后减法结果是正确的秒数)或者这些时间戳是否来自两个不同的分钟(然后减法结果似乎被填充/四舍五入到最近的分钟),从而产生反直觉的结果。

这是一个小演示(基本上使用 now() 和“20 秒前”):

root@localhost> maria "select now(), now() - interval 60 * 1/3 second,  now() - interval 60000000 * 1/3 microsecond, now() - (now() - interval 60 * 1/3 second), now() - (now() - interval 60000000 * 1/3 microsecond), TIMESTAMPDIFF( second,  now() - interval 60 * 1/3 second, now()) from dual"
2020-02-03 13:51:59.0
2020-02-03 13:51:39.0
2020-02-03 13:51:39.0
20.0000
20.000000
20
root@localhost> maria "select now(), now() - interval 60 * 1/3 second,  now() - interval 60000000 * 1/3 microsecond, now() - (now() - interval 60 * 1/3 second), now() - (now() - interval 60000000 * 1/3 microsecond), TIMESTAMPDIFF( second,  now() - interval 60 * 1/3 second, now()) from dual"
2020-02-03 13:52:02.0
2020-02-03 13:51:42.0
2020-02-03 13:51:42.0
60.0000
60.000000
20

我知道TIMESTAMPDIFF看起来不错,并且可以相应地重写SQL(只需要确保如何正确使用亚秒精度,给定“20.4秒> 20.2秒”将返回false 一旦四舍五入到 1 秒精度)。

我的主要问题 - 我的 MariaDB 设置有问题吗?或者这是特定 MariaDB 版本中的已知错误?还是设计使然?

最佳答案

这是设计使然。 MariaDB/MySQL 中的 DATETIME 算术不符合您的预期。

表示 YYYY-MM-DD HH:MM:SS 的 DATETIME 值被强制转换为表示为 YYYYMMDDHHMMSS 的十进制数(例如,对于缺少的秒数用零值填充)。

来自 MySQL 的示例:

mysql> SELECT CAST('2020-02-02 00:01' AS DATETIME) - CAST('2020-02-02 00:00:01' AS DATETIME),
    -> 20200202000100 - 20200202000001 \G
*************************** 1. row ***************************
CAST('2020-02-02 00:01' AS DATETIME) - CAST('2020-02-02 00:00:01' AS DATETIME): 99
                                               20200202000100 - 20200202000001: 99
1 row in set (0.00 sec)

正如您所发现的,您必须使用特定于日期/时间操作的函数来进行此类算术。

关于mysql - mariadb/mysql NOW() 和 TIMESTAMPDIFF 行为 - 是设计使然吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60041119/

相关文章:

php - 在 MySQL 中使用什么函数来散列密码?

javascript - Python 与 Javascript 日期时间

c# - Windows 时间戳格式(MOUSEMOVEPOINT 返回值的类型)

mysql - 在哪种情况下,将ID字段添加到多对多表可能是个好主意?

mysql - 加载哑巴数据库并运行所有迁移

java - Timestamp 的 SimpleDateFormat 使用 getTime() 方法失去精度

timezone - MariaDB 在配置中设置时区

mysql - 子查询 MYSQL 以从服务器选择所有数据库

mysql - 根据现有表中的值为表生成另一列

mysql - 大型SQL数据库-解决效率