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
上一篇: BigDecimal的运算——加减乘除
下一篇: 47:全排列 II
推荐阅读
-
MySQL中查询json格式的字段实例详解
-
php查询mysql数据库并将结果保存到数组的方法
-
PHP使用mysql_fetch_object从查询结果中获取对象集的方法
-
mysql的一个坑。修改或者删除的时候不能直接调用子查询的结果集
-
详解 Mysql查询结果顺序按 in() 中ID 的顺序排列
-
如何实现在分组的情况下,以另一个时间字段查询出结果?
-
在mysql中使用模糊查询时,使用中文查询结果不正确问题的解决办法
-
mysql数据库表的创建以及字段的增删改查操作及一些常用的查询命令介绍
-
深入理解用mysql_fetch_row()以数组的形式返回查询结果
-
mysql查询字段类型为json时的两种查询方式