本节提供一些示例,显示MySQL中的精确数学查询结果。这些例子说明了中描述的原则第12.22.3节,“表达式处理”,第12.22.4节,“舍入行为”。
示例1。在可能的情况下,数字与它们的确切值一起使用:
mysql >选择(。1 + 2) = 3;+----------------+ | (.1+。2) = .3 | +----------------+ | 1 | +----------------+
对于浮点值,结果是不精确的:
mysql >选择(。1E0 + .2E0) = .3E0; +----------------------+ | (.1E0 + .2E0) = .3E0 | +----------------------+ | 0 | +----------------------+
另一种查看精确值和近似值处理差异的方法是将一个小数字多次相加。考虑下面的存储过程,它添加了。
到一个变量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;结束时;选择d, f;结束;
两者的总和d
和f
逻辑上应该是1,但这只适用于十进制计算。浮点计算引入了较小的误差:
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
示例2。乘法是按照标准SQL所需的规模执行的。也就是说,对于两个数字X1
和X2
有规模S1
和S2
,结果的规模是
:S1
+S2
mysql> SELECT .01 * .01;+-----------+ | . 1 * . 01 | +-----------+ | 0.0001 | +-----------+
示例3。精确值的舍入行为定义如下:
舍入行为(例如,使用圆的()
函数)独立于底层C库的实现,这意味着从平台到平台的结果是一致的。
精确值列的舍入(
小数
和整数)和精确值的数字使用”四舍五入”规则。小数部分为。5或更大的值会从0四舍五入到最接近的整数,如下所示:mysql> SELECT ROUND(2.5), ROUND(-2.5);+------------+-------------+ | (-2.5(2.5) |轮 ) | +------------+-------------+ | 3 | 3 | +------------+-------------+
浮点值的舍入使用C库,而C库在许多系统上使用”四舍五入”规则。小数部分正好在两个整数中间的值被舍入到最接近的偶数:
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);+--------------+---------------+ | 轮(2.5 e0) | (-2.5 e0 ) | +--------------+---------------+ | 2 | 2 | +--------------+---------------+
示例4。在严格模式下,插入超出列范围的值会导致错误,而不是截断合法值。
当MySQL不是在严格模式下运行时,截断到一个合法的值发生:
mysql >设置sql_mode = ";mysql> CREATE TABLE t (i TINYINT);mysql> INSERT INTO t SET i = 128;mysql> SELECT i FROM t; mysql> SELECT i FROM t;+------+ | 我 | +------+ | 127年 | +------+ 1行集(0.00秒)
但是,如果严格模式生效,则会出现错误:
mysql >设置sql_mode =“STRICT_ALL_TABLES”;mysql> CREATE TABLE t (i TINYINT);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空集(0.00秒)
示例5:在严格的模式和与ERROR_FOR_DIVISION_BY_ZERO
设置,除零导致错误,而不是结果零
。
在非严格模式下,除零的结果是零
:
mysql >设置sql_mode = ";mysql> CREATE TABLE t (i TINYINT);mysql> INSERT INTO t SET i = 1 / 0;mysql> SELECT i FROM t; mysql> SELECT i FROM t;+------+ | 我 | +------+ | 零 | +------+ 1行集(0.03秒)
但是,如果正确的SQL模式有效,则除零是错误的:
mysql >设置sql_mode =“STRICT_ALL_TABLES, ERROR_FOR_DIVISION_BY_ZERO”;mysql> CREATE TABLE t (i TINYINT);mysql> INSERT INTO t SET i = 1 / 0;ERROR 1365(22012):除0 mysql> SELECT i FROM t;空集(0.01秒)
例子6。精确值字面量被计算为精确值。
近似值文字是用浮点数计算的,但是精确值文字被处理为小数
:
mysql> CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;查询OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 warning: 0 mysql> DESCRIBE t;+-------+-----------------------+------+-----+---------+-------+ | 字段默认零关键| | | | |类型多 | +-------+-----------------------+------+-----+---------+-------+ | |小数(2,1)无符号没有| | | 0.0 | | |不双| | | | 0 | | +-------+-----------------------+------+-----+---------+-------+ 2行集(0.01秒)
例7。如果聚合函数的实参是精确数值类型,则结果也是精确数值类型,其刻度至少是实参的刻度。
考虑这些语句:
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;
只有浮点参数的结果是double。对于精确类型参数,结果也是一个精确类型:
mysql>描述y;+ -------- + -------------- + ------ + ----- + --------- + ------- + |领域|型号null |钥匙|默认额外|+ -------- + -------------- + ------ + ----- + --------- + ------- + |AVG(i)| decimal(14,4) | YES | | NULL | | | AVG(d) | decimal(14,4) | YES | | NULL | | | AVG(f) | double | YES | | NULL | | +--------+---------------+------+-----+---------+-------+
只有浮点参数的结果是double。对于精确类型参数,结果也是一个精确类型。