[TOC]

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

问题描述

假如我们有如下一个数据表test,建表语句如下

CREATE TABLE test (

id int(11) NOT NULL AUTO_INCREMENT,

field1 bigint(10) DEFAULT NULL,

field2 decimal(10,0) DEFAULT NULL,

field3 int(10) DEFAULT NULL,

field4 float(15,4) DEFAULT NULL,

field5 float(15,4) DEFAULT NULL,

field6 float(15,4) DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我们创建了一个名为test的表,出了id字段之外还包含了多个字段,拥有这不同的数据类型。我们向这个表中插入一条数据

INSERT INTO test (field1, field2, field3, field4, field5, field6) VALUE (100, 100, 100, 1.005, 3.5, 2.5);

插入之后表中的数据是这样的

mysql> select * from test;

+----+--------+--------+--------+--------+--------+--------+

| id | field1 | field2 | field3 | field4 | field5 | field6 |

+----+--------+--------+--------+--------+--------+--------+

| 1 | 100 | 100 | 100 | 1.0050 | 3.5000 | 2.5000 |

+----+--------+--------+--------+--------+--------+--------+

1 row in set (0.00 sec)

如果现在我们执行下面这个SQL,你觉得结果会是什么样的呢?

SELECT

round(field1 * field4),

round(field2 * field4),

round(field3 * field4),

round(field1 * 1.005),

round(field2 * 1.005),

round(field3 * 1.005),

round(field5),

round(field6)

FROM test;

最初一直以为这样的结果肯定是都是101,因为上面这六个取值结果都是对100 * 1.005进行四舍五入,结果肯定都是101才对,而后面两个肯定是4和3才对,但是最终的结果却是与设想的大相径庭

*************************** 1. row ***************************

round(field1 * field4): 100

round(field2 * field4): 100

round(field3 * field4): 100

round(field1 * 1.005): 101

round(field2 * 1.005): 101

round(field3 * 1.005): 101

round(field5): 4

round(field6): 2

1 row in set (0.00 sec)

为什么会这样?

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

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

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函数的结果可以明确的看确实是转换为了最近的偶数。

总结

从这个例子中可以看到,在MySQL中使用ROUND还是要非常需要注意的,特别是当参与计算的字段中包含浮点数的时候,这个时候计算结果是不准确的。

本文将会持续修正和更新,最新内容请参考我的 GITHUB 上的 程序猿成长计划 项目,欢迎 Star,另外,求follow

mysql round 四舍五入_MySQL之ROUND函数四舍五入的陷阱相关推荐

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

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

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

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

  3. mysql substring用法_Mysql字符串截取函数SUBSTRING的用法说明

    函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...

  4. mysql count 类型_MYSQL的COUNT函数

    数据库经常用于回答这个问题,"某个类型的数据在表中出现的频度?"例如,你可能想要知道你有多少宠物,或每位主人有多少宠物,或你可能想要对你的动物进行各种类型的普查. 计算你拥有动物的 ...

  5. mysql range用法_MySQL的常用函数

    MySQL常用函数 用户信息 系统用户名 mysql> select system_user(); 所有用户名 mysql> select user(); 当前用户名 mysql> ...

  6. mysql存储过程时间_mysql时间操作函数和存储过程

    因为业务须要统计一批数据.用到关于mysql的时间操作函数和存储过程,问题已经基本解决.把过程记录下: 1. mysql的语句中不支持直接用循环.循环仅仅能在存储过程中使用. 2. 写为文件时,注意一 ...

  7. phpfind mysql怎么用_MySQL 的 find_in_set 函数使用方法

    举个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文...1,12,13 等等 . 现在有篇文章他既是 头条,又是热点,还是图文, type中以 1, ...

  8. mysql 存储过程求和_MySQL - 存储过程和函数

    MySQL - 存储过程和函数 创建和调用存储过程 -- 创建stu_group()存储过程,封装 分组查询总成绩,并按照总成绩升序排序的功能 -- 注意: DELIMITER 必须写在一行的最前面, ...

  9. mysql 查询 集合_MySQL使用集合函数进行查询操作实例详解

    本文实例讲述了MySQL使用集合函数进行查询操作.分享给大家供大家参考,具体如下: COUNT函数 SELECT COUNT(*) AS cust_num from customers; SELECT ...

最新文章

  1. 基于nginx的正向代理实现
  2. 门户网站建设与运营需要付出更多成本
  3. JPA 注解的CascadeType属性
  4. SQL语句中大于等于小于的写法
  5. 償債基金(Sinking fund)
  6. Java:检查器框架
  7. 使用Java中的equals()和compareTo()方法比较字符串
  8. linux下usb调试工具,LINUX USB调试
  9. java集合中retainAll方法
  10. VB6中给数组赋值的限制
  11. fabricjs上手指南
  12. mysql主从延迟设置
  13. 配置多个git账号_git配置账号(用户名/邮箱)
  14. 联想万全服务器告警信息在哪里看,华为网络设备查看告警信息
  15. uboot移植——uboot配置过程详解
  16. ios客户端学习-手机屏幕尺寸
  17. 【开发教程6】疯壳·ARM功能手机-中断实验教程
  18. 网络工程师考试常用计算公式汇总
  19. LVS负载均衡器的原理简单介绍
  20. 如何自己赚取csdn金币

热门文章

  1. 操作 Wave 文件(13): waveOutGetVolume、waveOutSetVolume
  2. Visual Studio 剪切板新特性
  3. 字符串中的第一个唯一字符
  4. 远程控制 开源 鳄梨_开发人员关系与鳄梨的共同点
  5. LeetCode 312. 戳气球(Burst Balloons)
  6. Bootstrap 标签导航的布局
  7. java 枚举 大小_Java枚举入门
  8. Git笔记(1) 版本控制
  9. 有了代码怎么用python爬虫_python实现简单爬虫功能
  10. php 微信实时更新,微信小程序修改data使页面数据实时更新的代码示例