Mysql 查询float类型的字段查询不到结果

问题:

select * from payments where status = 1 and payment_fee = 0.31

查询结果为空(可四数据库明明有一条数据满足条件的)

解决:

  • 使用format
select * from payments where status = 1 and  format(payment_fee,2) = format(0.31,2);
  • 使用concat
select * from payments where status = 1 and  concat(payment_fee, '') = '0.31'
  • 使用like
select * from payments where status = 1 and payment_fee like 0.31

原因深究:

大意:FLOAT和DOUBLE类型表示近似数字数据值。 MySQL对单精度值使用四个字节,对双精度值使用八个字节。

对于FLOAT,SQL标准允许在括号中的关键字FLOAT后面的位中指定精度(而不是指数的范围)的可选规范。 ;即FLOAT(p)。 MySQL还支持此可选的精度规范,但是FLOAT(p)中的精度值仅用于确定存储大小。从0到23的精度导致4字节单精度FLOAT列。从24到53的精度将导致8字节的双精度DOUBLE列。

MySQL允许使用非标准语法:FLOAT(M,D)或REAL(M,D)或DOUBLE PRECISION(M,D)。在此,(M,D)表示总共可以存储多达M位的值,其中D位可以在小数点后。例如,显示为FLOAT(7,4)的列看起来像-999.9999。 MySQL在存储值时执行四舍五入,因此,如果将999.00009插入FLOAT(7,4)列,则近似结果为999.0001。

由于浮点值是近似值而不是作为精确值存储的,因此在比较中尝试将它们视为精确值可能会导致问题。它们还受平台或实现依赖性的约束。有关更多信息,请参见第B.4.4.8节“浮点值的问题”

为了获得最大的可移植性,需要存储近似数值数据值的代码应使用FLOAT或DOUBLE PRECISION,而没有规定精度或位数。

以上大意: 使用基于语句的复制,值从十进制转换为二进制。由于十进制和二进制表示形式之间的转换可能是近似的,因此涉及浮点值的比较是不精确的。对于显式使用浮点值或隐式转换为浮点值的操作,这是正确的。由于计算机架构,用于构建MySQL的编译器等方面的差异,浮点值的比较可能在主服务器和从属服务器上产生不同的结果。

ps:
float类型不指定精度时,对float列的精确检索可能不正确。
使用float还会存在一个问题是insert时会存在数据丢失问题。
例如我insert一个字段为 131072.32 的值到数据库,成功之后实际到数据库的是 131072.31。。。少了0.01.。。。所以float大家还是要慎用

关于MySQL如何选择float, double, decimal可以参考这篇文章,通俗易懂:
http://blog.leanote.com/post/weibo-007/mysql_float_double_decimal

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值