如何避免MySQL查询中的浮点运算?

如何避免MySQL查询中的浮点运算?,mysql,math,decimal,bigdecimal,Mysql,Math,Decimal,Bigdecimal,假设我有两列,A和B,类型为DECIMAL(9,2) 现在,假设我运行以下查询: SELECT SUM(A) / SUM(B) SELECT SUM(A) / SUM(B) * 100 我的理解是,这个除法不会通过浮点运算完成,因为两列都是十进制类型。这是正确的吗 另外,假设我运行以下查询: SELECT SUM(A) / SUM(B) SELECT SUM(A) / SUM(B) * 100 100将如何影响查询?这是否会导致MySQL执行浮点运算?如果是这样的话,我怎样才能避免呢 这

假设我有两列,A和B,类型为
DECIMAL(9,2)

现在,假设我运行以下查询:

SELECT SUM(A) / SUM(B)
SELECT SUM(A) / SUM(B) * 100
我的理解是,这个除法不会通过浮点运算完成,因为两列都是
十进制类型。这是正确的吗

另外,假设我运行以下查询:

SELECT SUM(A) / SUM(B)
SELECT SUM(A) / SUM(B) * 100
100
将如何影响查询?这是否会导致MySQL执行浮点运算?如果是这样的话,我怎样才能避免呢

这是否会导致MySQL执行浮点运算

我想说您应该参考SQL标准,但作为MySQL,可能不是计算实际情况的最可靠方法:)

如何避免[意外的浮点类型转换]

我要做的是明确地将值设置为适合您的类型:

SUM(A) / SUM(B) * CAST(100.0 AS DECIMAL(9,2)) 
明确无误,有助于为未来用户提供文档

100将如何影响查询?这是否会导致MySQL执行浮点运算?如果是这样的话,我怎样才能避免呢

100是一个精确的数值文字,这里我们用十进制除以十进制乘以十进制(整数)=>结果仍然是十进制(但精度更高)

精确值数字文字具有整数部分或小数部分,或两者兼有。可以签字。示例:1、.2、3.4、-5、-6.78、+9.10

近似值数字文字用科学符号表示,带有尾数和指数。一方或双方均可签字。示例:1.2E3、1.2E-3、-1.2E3、-1.2E-3

两个看起来相似的数字可能会被区别对待。例如,2.34是一个精确值(定点)数,而2.34E0是一个近似值(浮点)数

例如:

CREATE TABLE t(A DECIMAL(9,2), B DECIMAL(9,2));

CREATE TABLE r1 AS SELECT SUM(A) / SUM(B) AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r1';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | decimal(37,6) |
+--------------+---------------+

CREATE TABLE r2 AS SELECT SUM(A) / SUM(B) * 100 AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r2';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | decimal(40,6) |
+--------------+---------------+
现在使用近似值numeric literal
100E0

CREATE TABLE r3 AS SELECT SUM(A) / SUM(B) * 100E0 AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r3';
+--------------+-------------+
| COLUMN_NAME  | COLUMN_TYPE |
+--------------+-------------+
| result       | double      |
+--------------+-------------+


值得注意的是,有些操作可能看起来完全相同,但返回的数据类型不同。例如:

CREATE TABLE r4 AS SELECT POWER(A,2) AS result, A*A AS result2 FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r4';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | double        |
| result2      | decimal(18,4) |
+--------------+---------------+
SELECT ROUND(100 * sum(...) / sum(...), 1) ...

与其争论计算的细节,不如格式化结果。例如:

CREATE TABLE r4 AS SELECT POWER(A,2) AS result, A*A AS result2 FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r4';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | double        |
| result2      | decimal(18,4) |
+--------------+---------------+
SELECT ROUND(100 * sum(...) / sum(...), 1) ...
这就是小数点后一位的百分比


当您需要“数千个分隔符”(不可能是百分比)时,请参阅
FORMAT()
函数。

请提供结果不同的情况。有没有避免浮动的理由?MySQL总是很擅长得到“正确”的答案。@RickJames我在做涉及金额的计算。在Java中,我会使用大小数,在PHP、bcmath或像brick/math这样的库中使用大小数。我不确定MySQL中的等价物是什么。根据我的阅读资料和测试,我概述的问题提供了“正确”的答案,但我想与比我更了解MySQL的人再次核实。我一直在思考这个问题,但遗憾的是,我没有一个明确的答案。对于像美元和美分这样简单的东西,加上简单的加法,所有的总和都应该是精确的。但当你需要除法或银行业批准的四舍五入时,我会怀疑。如果你需要除法或银行业批准的四舍五入,那么当你需要除法或四舍五入时,我会怀疑。我的理解是,这种除法不会通过浮点算术来完成,因为两列都是十进制类型。这是正确的吗?(1) (2)(3)根据惯例:如果没有显式强制转换,表达式的结果将四舍五入到最精确的操作数小数位数,但不小于6。