在MySQL中, ROUND 函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并无预期的那样,本文将这一问题记录下来,并提出解决方案。

问题描述

假如咱们有以下一个数据表 test ,建表语句如下:

CREATETABLEtest (idint(11) NOT NULL AUTO_INCREMENT,field1bigint(10) DEFAULT NULL,field2decimal(10,0) DEFAULT NULL,field3int(10) DEFAULT NULL,field4float(15,4) DEFAULT NULL,field5float(15,4) DEFAULT NULL,field6float(15,4) DEFAULT NULL,PRIMARYKEY (id)
) ENGINE=InnoDBDEFAULT CHARSET=utf8;

咱们建立了一个名为 test 的表,出了 id 字段以外还包含了多个字段,拥有这不一样的数据类型。咱们向这个表中插入一条数据sql

INSERTINTOtest (field1, field2, field3, field4, field5, field6) VALUE (100, 100, 100, 1.005, 3.5, 2.5);

插入以后表中的数据是这样的数据库

mysql> select * fromtest;
+----+--------+--------+--------+--------+--------+--------+
| id | field1 | field2 | field3 | field4 | field5 | field6 |
+----+--------+--------+--------+--------+--------+--------+
|  1 |    100 |    100 |    100 | 1.0050 | 3.5000 | 2.5000 |
+----+--------+--------+--------+--------+--------+--------+
1 rowin set (0.00 sec)

若是如今咱们执行下面这个SQL,你以为结果会是什么样的呢?app

SELECTround(field1 * field4),round(field2 * field4),round(field3 * field4),round(field1 * 1.005),round(field2 * 1.005),round(field3 * 1.005),round(field5),round(field6)
FROMtest;

最初一直觉得这样的结果确定是都是 101 ,由于上面这六个取值结果都是对 100 * 1.005 进行四舍五入,结果确定都是 101 才对,然后面两个确定是 4 和 3 才对,可是最终的结果倒是与设想的截然不同函数

*************************** 1. row ***************************
round(field1 * field4): 100
round(field2 * field4): 100
round(field3 * field4): 100round(field1 * 1.005): 101round(field2 * 1.005): 101round(field3 * 1.005): 101round(field5): 4round(field6): 2
1 rowin set (0.00 sec)

为何会这样?

一样是100*1.005,为何从数据库中的字段相乘获得的结果和直接字段与小数相乘获得的不同呢?this

对这个问题百思不得其解,各类百度谷歌无果。。。没办法,还得靠本身,这个时候最有用的就是官网文档了,因而查询了mysql官方文档中关于ROUND函数的部分,其中包含下面两条规则spa

  • For exact-value numbers, ROUND() uses the “round half up” rule(对于精确的数值, ROUND 函数使用四舍五入)
  • For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with any fractional part is rounded to the nearest even integer. (对于近似值,则依赖于底层的C函数库,在不少系统中 ROUND 函数会使用“取最近的偶数”的规则)

经过这两条规则,咱们能够看出,因为咱们在使用两个字段相乘的时候,最终的结果是按照 float 类型处理的,而在计算机中 float 类型不是精确的数,所以处理结果会按照第二条来,而直接整数字段与1.005这样的小数运算的结果是由于两个参与运算的值都是精确数,所以按照第一条规则计算。从 field5 和 field6 执行 ROUND 函数的结果能够明确的看确实是转换为了最近的偶数。

解决办法

1.改变表中数字的数据类型

使用精确的数字类型Decimal或者numberic定义字段,

2.强制类型转换

保留两位小数时:Convert(val,decimal(10,2))
保留两位小数且小数点后为零不显示:
Convert(Convert(decimal(10,2),val),FLOAT)保留小数位数为两位或多位:
需要用到:Convert ( VAL, decimal ( int i , int j ) , ) 此方法
其中的参数代表的意思
i : decimal 的长度
j : 当前查询的结果需要的小数位数(保留两位就是2,三位就是3 … …)
VAL:需要进行处理的数据(此数据可以用计算公式代替)需要保留两位小数且小数点后为零不显示:
需要用到:Convert (VAL, FLOAT  ) 此方法

3.编写自定义四舍五入函数

CREATE FUNCTION f_RoundEx (@VAL FLOAT,-- 需要几舍几入的值@Digit INT,-- 保留小数位数@point INT -- 确定是几舍
) RETURNS FLOAT AS
BEGINDECLARE @Factor FLOAT,@result FLOAT ,@fPoint FLOAT;SET @Factor = power(10 ,@Digit);SET @fPoint = (10 -@point - 1) * 0.1;IF @VALSET @result = floor(@VAL *@Factor - @fPoint) / @Factor;ELSESET @result = floor(@VAL * @Factor + @fPoint) / @Factor RETURN @result;
END;

总结

从这个例子中能够看到,在MySQL中使用ROUND仍是要很是须要注意的,特别是当参与计算的字段中包含浮点数的时候,这个时候计算结果是不许确的。

MySQL : ROUND 函数四舍五入陷阱及解决办法相关推荐

  1. mysql round不四舍五入_MySQL中ROUND函数进行四舍五入操作陷阱分析

    本文实例讲述了MySQL中ROUND函数进行四舍五入操作陷阱.,具体如下: 在MySQL中, ROUND函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没有预期的那样,本 ...

  2. mysql round 四舍五入_MySQL之ROUND函数四舍五入的陷阱

    [TOC] 在MySQL中,ROUND函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没有预期的那样,本文将这一问题记录下来,以免大家跟我一样犯同样的错误. 问题描述 假 ...

  3. mysql decimal被四舍五入_MySQL之ROUND函数四舍五入的陷阱

    在MySQL中,ROUND函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没有预期的那样,本文将这一问题记录下来,以免大家跟我一样犯同样的错误. 问题描述 假如我们有如下 ...

  4. MySQL 之 ROUND 函数四舍五入的陷阱

    在MySQL中, ROUND 函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没有预期的那样,本文将这一问题记录下来,以免大家跟我一样犯同样的错误. 问题描述 假如我们有 ...

  5. linux mysql 超级用户_Linux下MySQL忘记超级用户口令的解决办法linux操作系统 -电脑资料...

    以前我都是讲述在windows中忘记了mysql root密码的找回方法,下面我来介绍在Linux下MySQL忘记超级用户口令的解决办法,有碰到此类问题的同学可进入参考, 解决办法一 MySQL忘记超 ...

  6. mysql-8.0.17解压版安装步骤及MySQL服务无法启动问题的解决办法

    mysql-8.0.17解压版安装步骤及MySQL服务无法启动问题的解决办法 参考文章: (1)mysql-8.0.17解压版安装步骤及MySQL服务无法启动问题的解决办法 (2)https://ww ...

  7. Can't connect to MySQL server on 'localhost' (10061)的解决办法!

    Can't connect to MySQL server on 'localhost' (10061)的解决办法! http://blog.sina.com.cn/s/blog_52ebca1f01 ...

  8. Mysql遇到Too many connections的解决办法

    Mysql遇到Too many connections的解决办法 由于线上mysql实例太多,因此也就经常遇到Too many connections的问题,这个问题也是最常见的问题,下面就结合自己的 ...

  9. 安装32位mysql报错_在CentOS中安装32位或64位MySql报错error: Failed dependencies解决办法...

    在CentOS中安装MySql报错error: Failed dependencies解决办法 安装64位MySql报错内容如下: error: Failed dependencies: libaio ...

最新文章

  1. java struts2相关记录
  2. sql 关联使用id还是code_使用sh格式化nginx访问日志并存入mysql
  3. 宝马奥迪工厂模式_宝马的完整形式是什么?
  4. python 文件指针及文件覆盖
  5. iOS之友盟简单分享(第三方)及sso授权问题
  6. Protel 99se 快捷键
  7. 《分布式任务调度平台XXL-JOB》
  8. Javascript特效:五彩小球
  9. 计算机教育影片观后感,2020青少年法治教育片沉重的爱观后感大全
  10. java测试复盘2(2019.8.21)
  11. 大数据浪潮将催生信息产业第三极——“数据极”
  12. 嵌入式--LCD常用接口介绍
  13. 怎么调用计算机任务管理器,如何使用任务管理器
  14. Hive练习题之列转行
  15. CF3B--Lorry翻译
  16. 利用python改图片为任意颜色
  17. 大数据初学者应该知道的知识
  18. PTA L1-013:计算阶乘和 (python)
  19. 工程建设项目人员履约数字化管理系统
  20. 新型消防机器人作文_未来的消防机器人作文600字

热门文章

  1. JavaSE基础知识汇总
  2. php笔试攻略,php笔试(一)
  3. php ftp 时间不对,ftp时间差8小时引起的?
  4. 报错:找不到模块“antd-mobile (也可以是其他的模块)”或其相应的类型声明。
  5. 仙剑游戏系列..感想
  6. 记Git报错-Everything up-to-date
  7. linux 局域网 提高网速,提高Linux系统网速的方法
  8. 微信发朋友圈如何只发文字?
  9. 关于将微博上视频保存在电脑本地的方法汇总
  10. 刷题之旅第35站,CTF show 萌新题目集合