今天测试代码数据的时候,发现一个问题,就是 1.125--> 使用round() 函数取2位小数点额时候,结果是1.12而不是预期结果1.13.
-- 背景大概就是:从一个参数表里面取一个参数进行运算,结果要四舍五入保留两位小数。
-- 参数表的字段属性为 varchar
select test_round into @v_value from t_test_rowid where a = 1;
select round((10.5-@v_value)/2, 2) as new_value
出现该问题的原因,与参数类型有关。
①仅当参与运算的所有参数的参数类型是“数值”类型的,运算结果才是“数值”,round() 采用“四舍五入”的原则求得最后的结果。
②当有字符串类型的数据参与运算时,得到的结果是“字符串”类型的,结果使用round()函数采用“四舍六入五成双”的原则求得最终的结果。
解决方案:
可以将字符串类型的数据转换成数字类型的参数。
cast('1.125' as decimal(18,2))
关于以上两点可以参考以下2个连接:
链接一《关于MySQL的ROUND函数四舍五入的细节分析_BlueEyesHolder的博客-CSDN博客》
引子
在群里,有人问了这么一个问题,引起了我的兴趣。查询之后感觉打开了新世界的大门,因此记录一下,以作备忘(MySQL版本:5.7.17-log)。#执行: SELECT ROUND(1.3225, 3); #结果: 1.323 #执行: SELECT ROUND('1.3225', 3); #结果: 1.322
MySQL的ROUND()函数:
ROUND(X)或ROUND(X,D),简单来说作用是返回X四舍五入到小数点后第D位(默认0)的值,即:#执行: SELECT ROUND(-1.23); #结果: -1 #执行: SELECT ROUND(1.298, 1); #结果: 1.3
回到上面的问题,为什么看似相同的语句执行出来的结果不同,其实可以从官方文档[1]中找到端倪(以下是我自己的翻译,如果有误谢谢指出):
ROUND() uses the following rules depending on the type of the first argument:
ROUND()根据第一个参数的类型来应用以下(不同)的规则:
For exact-value numbers, ROUND() uses the “round half away from zero”
or “round toward nearest” rule: A value with a fractional part of .5
or greater is rounded up to the next integer if positive or down to
the next integer if negative. (In other words, it is rounded away from
zero.) A value with a fractional part less than .5 is rounded down to
the next integer if positive or up to the next integer if negative.对于精确值的数字,ROUND()使用”中间值朝远离0点方向舍入“或”朝最近舍入“规则:一个小数部分为.5或更大的值,若为正则向上舍入,若为负则向下舍入。(换而言之,就是向远离0的方向舍入。)一个小数部分小于.5的值,若为正则向下舍入,若为负则向上舍入。
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 a fractional part exactly halfway between two
integers is rounded to the nearest even integer.对于近似值的数字,返回结果取决于C库。在许多系统中,这意味着ROUND()使用”舍入最接近的偶数“规则:一个值的小数部分正好在两个整数中间时,舍入到最接近的偶数。
解答
根据以上规则,我们可以推断,MySQL自动将‘1.3225’这个字符串转换为了一个近似值数字。
那么,在MySQL中(仅针对MySQL 5.7),哪些数值型数据类型对应的是精确值的数字呢,以下就是答案:
1)整型:INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT
2)定点型:DECIMAL, NUMERIC
值得注意的是,浮点型并不在列,这也就是为什么会出现开头问题的原因。
————————————————
版权声明:本文为CSDN博主「BlueEyesHolder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/BlueEyesHolder/article/details/108426950
链接二《SQL中Round函数没有四舍五入原因及处理方法_round不四舍五入_独特的弧度的博客-CSDN博客》
为什么我们在写sql使用round函数四舍五入时,明明后面是5可以进位反而舍掉了那?
原因在于“四舍六入五成双”原则(来源于百度百科)
对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”,这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:
(1)5前为奇数,舍5入1;
(2)5前为偶数,舍5不进(0是偶数)。解决方案:
采用CAST函数,用于将某种数据类型的表达式显式转换为另一种数据类型。CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型。语法:CAST (expression AS data_type)
例如:SELECT CAST(‘11.115’ as decimal(3, 2))
decimal函数,这里的3是这个小数的位数有多少位, 一般最大不超过38位,当然直接写38也可以,
后面的参数中的2是小数点后取几位, 是2就取两位, 是3就取三位! 并且是四舍五入后的结果!
————————————————
版权声明:本文为CSDN博主「独特的弧度」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43674919/article/details/109776597