mysql - MySQL舍入怪异
问题描述
我正在开发一个发票模块,当我计算四舍五入的金额时遇到了一些奇怪的问题,我无法绕开我的脑袋。
在 mysql shell 中执行此查询时,我得到不同的结果:
SELECT @amount := 1.005 AS decimalAmount, @rounded := ROUND(@amount) AS rounded, @diff := ROUND(@rounded - @amount, 2) AS roundOff, ROUND(@diff * 1e2) centsRounded;
我第三次运行查询它显示了我正在寻找的结果,但第一次和第二次不是出于某种原因。
+---------------+---------+----------+--------------+
| decimalAmount | rounded | roundOff | centsRounded |
+---------------+---------+----------+--------------+
| 1.005 | 1 | -0.00 | -0 |
+---------------+---------+----------+--------------+
1 row in set (0.000 sec)
+---------------+---------+----------+--------------+
| decimalAmount | rounded | roundOff | centsRounded |
+---------------+---------+----------+--------------+
| 1.005 | 1 | -0.00 | -0 |
+---------------+---------+----------+--------------+
1 row in set (0.000 sec)
+---------------+---------+----------+--------------+
| decimalAmount | rounded | roundOff | centsRounded |
+---------------+---------+----------+--------------+
| 1.005 | 1 | -0.01 | -1 |
+---------------+---------+----------+--------------+
1 row in set (0.000 sec)
有人可以解释为什么会这样吗?
解决方案
有人可以解释为什么会这样吗?
说明书解释_
涉及用户变量的表达式的求值顺序未定义。例如,不能保证 SELECT @a, @a:=@a+1 先计算 @a 然后再执行赋值。
很确定您的查询中的评估是错误的。
如果您真的不需要 MySQL 用户变量,则很难避免使用它们。
我更想重写这个查询。
SELECT
@amount := 1.005 AS decimalAmount
, @rounded := ROUND(@amount) AS rounded
, @diff := ROUND(@rounded - @amount, 2) AS roundOff
, ROUND(@diff * 1e2) centsRounded;
或多或少像(有更多的重写选项)以避免使用 MySQL 的用户变量。
SELECT
record.amount
, ROUND(record.amount) AS rounded
, ROUND(ROUND(record.amount) - record.amount, 2) AS roundOff
, ROUND(ROUND(record.amount) - record.amount, 2) * 1e2 AS centsRounded
FROM (
SELECT
1.005 AS amount
) AS record
结果
| amount | rounded | roundOff | centsRounded |
| ------ | ------- | -------- | ------------ |
| 1.005 | 1 | -0.01 | -1 |
看演示
推荐阅读
- java - 通过 t3 协议访问 weblogic 服务器上的 jndi 数据源与直接访问数据库有何不同?
- methods - ActiveRecord 通过 has_many 删除行:通过关联
- python - 将文档存储到 Elastic Search 中现有和不存在的字段中
- ios - 当我的应用程序根据条件关闭时,是否可以禁止推送通知?
- sql - 将 SQL Server 中已弃用的外连接运算符 *= 转换为左连接
- nestjs - 如何在 NestJS 中序列化 Prisma 对象?
- php - 如果没有可用的运输选项,则阻止查看结帐页面 WooCommerce
- expo - 事件监听器不会在 expo、react-navigation 中触发,但用于之前工作
- spring-boot - 将 Apache Spark 与 Spring Boot 集成
- javascript - 此表达式不可调用。类型'{店铺:typeof店铺;}' 没有调用签名。反应