This section provides some examples that show precision math query results in MySQL. 本节提供了一些示例,显示MySQL中的精确数学查询结果。These examples demonstrate the principles described in Section 12.25.3, “Expression Handling”, and Section 12.25.4, “Rounding Behavior”.这些示例演示了第12.25.3节,“表达式处理”和第12.25.4节,“舍入行为”中描述的原则。
Example 1. Numbers are used with their exact value as given when possible:在可能的情况下,数字与其精确值一起使用:
mysql> SELECT (.1 + .2) = .3;
+----------------+
| (.1 + .2) = .3 |
+----------------+
| 1 |
+----------------+
For floating-point values, results are inexact:对于浮点值,结果不精确:
mysql> SELECT (.1E0 + .2E0) = .3E0;
+----------------------+
| (.1E0 + .2E0) = .3E0 |
+----------------------+
| 0 |
+----------------------+
Another way to see the difference in exact and approximate value handling is to add a small number to a sum many times. 另一种观察精确值和近似值处理差异的方法是多次向和中添加一个小数字。Consider the following stored procedure, which adds 考虑下面的存储过程,将.0001
to a variable 1,000 times..0001
加到某个变量1000次。
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 0; DECLARE d DECIMAL(10,4) DEFAULT 0; DECLARE f FLOAT DEFAULT 0; WHILE i < 10000 DO SET d = d + .0001; SET f = f + .0001E0; SET i = i + 1; END WHILE; SELECT d, f; END;
The sum for both d
and f
logically should be 1, but that is true only for the decimal calculation. d
和f
的和在逻辑上应该是1,但这仅适用于十进制计算。The floating-point calculation introduces small errors:浮点计算引入了小错误:
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
Example 2. Multiplication is performed with the scale required by standard SQL. 乘法是按照标准SQL所要求的比例执行的。That is, for two numbers 也就是说,对于标度为X1
and X2
that have scale S1
and S2
, the scale of the result is
:S1
+ S2
S1
和S2
的两个数字X1
和X2
,结果的标度为S1+S2
:
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
| 0.0001 |
+-----------+
Example 3. Rounding behavior for exact-value numbers is well-defined:精确值数字的舍入行为定义明确:
Rounding behavior (for example, with the 舍入行为(例如,使用ROUND()
function) is independent of the implementation of the underlying C library, which means that results are consistent from platform to platform.ROUND()
函数)独立于底层C库的实现,这意味着不同平台的结果是一致的。
Rounding for exact-value columns (精确值列(DECIMAL
and integer) and exact-valued numbers uses the “round half away from zero” rule. DECIMAL
和整数)和精确值数字的舍入使用“从零舍入一半”规则。A value with a fractional part of .5 or greater is rounded away from zero to the nearest integer, as shown here:小数部分为.5或更大的值从零舍入到最接近的整数,如下所示:
mysql> SELECT ROUND(2.5), ROUND(-2.5);
+------------+-------------+
| ROUND(2.5) | ROUND(-2.5) |
+------------+-------------+
| 3 | -3 |
+------------+-------------+
Rounding for floating-point values uses the C library, which on many systems uses the “round to nearest even” rule. 浮点值的舍入使用C库,在许多系统上使用“舍入到最接近的偶数”规则。A value with a fractional part exactly half way between two integers is rounded to the nearest even integer:小数部分正好位于两个整数中间的值将四舍五入到最接近的偶数整数:
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);
+--------------+---------------+
| ROUND(2.5E0) | ROUND(-2.5E0) |
+--------------+---------------+
| 2 | -2 |
+--------------+---------------+
Example 4. In strict mode, inserting a value that is out of range for a column causes an error, rather than truncation to a legal value.在严格模式下,插入超出列范围的值会导致错误,而不是截断为合法值。
When MySQL is not running in strict mode, truncation to a legal value occurs:当MySQL不是在严格模式下运行时,会截断为合法值:
mysql>SET sql_mode='';
Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t SET i = 128;
Query OK, 1 row affected, 1 warning (0.00 sec) mysql>SELECT i FROM t;
+------+ | i | +------+ | 127 | +------+ 1 row in set (0.00 sec)
However, an error occurs if strict mode is in effect:但是,如果严格模式生效,则会发生错误:
mysql>SET sql_mode='STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 128;
ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1 mysql>SELECT i FROM t;
Empty set (0.00 sec)
Example 5: In strict mode and with 在严格模式下,如果设置了ERROR_FOR_DIVISION_BY_ZERO
set, division by zero causes an error, not a result of NULL
.ERROR_FOR_DIVISION_BY_ZERO
,则除0将导致错误,而不是NULL
的结果。
In nonstrict mode, division by zero has a result of 在非严格模式下,被零除的结果为NULL
:NULL
:
mysql>SET sql_mode='';
Query OK, 0 rows affected (0.01 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 1 / 0;
Query OK, 1 row affected (0.00 sec) mysql>SELECT i FROM t;
+------+ | i | +------+ | NULL | +------+ 1 row in set (0.03 sec)
However, division by zero is an error if the proper SQL modes are in effect:但是,如果正确的SQL模式生效,则除0是一个错误:
mysql>SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';
Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 1 / 0;
ERROR 1365 (22012): Division by 0 mysql>SELECT i FROM t;
Empty set (0.01 sec)
Example 6. Exact-value literals are evaluated as exact values.精确值文字将作为精确值进行计算。
Approximate-value literals are evaluated using floating point, but exact-value literals are handled as 近似值文字使用浮点计算,但精确值文字按DECIMAL
:DECIMAL
处理:
mysql>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;
Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>DESCRIBE t;
+-------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+-------+ | a | decimal(2,1) unsigned | NO | | 0.0 | | | b | double | NO | | 0 | | +-------+-----------------------+------+-----+---------+-------+ 2 rows in set (0.01 sec)
Example 7. If the argument to an aggregate function is an exact numeric type, the result is also an exact numeric type, with a scale at least that of the argument.如果聚合函数的参数是精确数字类型,则结果也是精确数字类型,其比例至少为参数的比例。
Consider these statements:考虑这些陈述:
mysql>CREATE TABLE t (i INT, d DECIMAL, f FLOAT);
mysql>INSERT INTO t VALUES(1,1,1);
mysql>CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
The result is a double only for the floating-point argument. 结果是一个双精度浮点参数。For exact type arguments, the result is also an exact type:对于精确类型参数,结果也是精确类型:
mysql> DESCRIBE y;
+--------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| AVG(i) | decimal(14,4) | YES | | NULL | |
| AVG(d) | decimal(14,4) | YES | | NULL | |
| AVG(f) | double | YES | | NULL | |
+--------+---------------+------+-----+---------+-------+
The result is a double only for the floating-point argument. 结果是一个双精度浮点参数。For exact type arguments, the result is also an exact type.对于精确类型参数,结果也是精确类型。