美文网首页
mysql踩坑集锦

mysql踩坑集锦

作者: 拾月初六 | 来源:发表于2019-08-14 15:56 被阅读0次

    1.round函数的四舍五入

    1.1问题解决

    今天在导出报表时,发现有个字段金额的值为 501.42990000000003元,很明显这是出现了精度丢失的问题了,于是我准备使用round函数进行四舍五入,取2位小数来使用,但是却发现round函数小坑不断。

    首先我们假定现在需要处理的值为 12345678.445
    如果此时这个值是数值类型,那么使用round函数得到的结果是


    看起来我们已经达到了目标是吗?
    但是由于我这个数值是varchar类型,实际的结果却是



    我们需要的四舍五入并没有达成。
    那么就是字符不能简单的使用round函数进行四舍五入,那么我们需要把字符转成数值进行操作了。
    第一次转换
    按照网上的经验,我们在字符串后面加了个0,结果却依然没有错误。



    第二次转换
    这个我们使用cast函数

    。。。。这次结果完全不对,为什么嗯?
    原因在于使用这个函数方法时,注意AS DECIMAL函数的2个参数,第一个9代表的是数值有效位,第二个2代表小数的有效位,按照(9,2)来处理的话,我们能得到的最大数值是9-2=7位的整数部分,和2位的小数部分,这样最大的数值也只能是图中 的9999999.99了,所以我们在使用这个函数时,要根据业务情况给出合适的数值位数,最后使用了20位长度,成功达成目标


    1.2 问题分析

    目标达成了,我们再回看下在这个问题处理中,我们都碰到了什么问题?

    1:为什么会出现最开始501.42990000000003元这种需要转换的数据?

    通过查看sql发现,这个金额是由单价*数量得到的,而我在表结构中,单价才用了Bigdecmal类型,而数值使用了varchaer类型,结果就是

    这就提醒我们,如果我们在建表时,严格按照业务数据类型建表,类似这个数量采用数值类型存储,就不出现的这种隐藏的BUG了。

    2: 为什么在处理round在处理字符串类型的数字时,会得到不到我们想要的结果。

    首先,round函数在处理时,会根据传入的参数,有不同的处理方法,
    参数会分成两类,一种是精确值,整数类型int和bigdecimal,另外一种都可以算成近似值数字,具体分类可以查看官方文档。
    mysql中关于精确值和近似值的定义

    分清楚参数类型后,如果是精确值,那么系统的操作就是我们通常理解的四舍五入了。

    mysql文档中关于舍入的说明
    如果是近似值的话按照以下四舍六入五成双规则处理

    1. 被修约的数字小于5时,该数字舍去;


      4小于5,被舍去
    2. 被修约的数字大于5时,则进位;

    6大于5,则进一位
    1. 被修约的数字等于5时,要看5前面的数字,若是奇数则进位,若是偶数则将5舍掉,


      5前面是奇数,进一位
    5前面是偶数,则舍去

    若5的后面还有不为“0”的任何数,则此时无论5的前面是奇数还是偶数,均应进位。

    因为5后面有值,全部进一位
    因为5后面有值,全部进一位

    此处参考了以下网友资料
    https://q.cnblogs.com/q/94377/

    相关文章

      网友评论

          本文标题:mysql踩坑集锦

          本文链接:https://www.haomeiwen.com/subject/fjhgjctx.html