Yii2中float(5,2)字段findOne查询部分值无结果问题
我之前处理过类似的问题,核心原因其实出在浮点数的近似存储特性上,结合你用的float(5,2)类型和精确匹配的查询方式,就导致了这种奇怪的现象:
问题原因分析
- 浮点数的近似存储特性:MySQL中的
float是单精度浮点数,属于近似数值类型。当存储十进制小数时,像7.8这种数值无法被二进制精确表示,数据库里实际存的是一个非常接近7.8的近似值;而78.00是整数,能被二进制精确存储,所以数据库里的数值和你传入的78.00/78.000完全一致。 - 精确匹配的矛盾:你用
where(['value' => $this->value])做等值查询时,程序里的7.8/7.80是精确的十进制数值,和数据库里存储的7.80的近似值做比较时,因为存在微小的精度差异,数据库会判定两者不相等,所以返回0行;而78.00的程序值和数据库存储值完全匹配,就能查到结果。
解决方案
- 优先改用定点数类型:把字段类型从
float(5,2)改成decimal(5,2)。decimal是精确数值类型,专门用于存储需要精确计算的十进制小数,存储和查询时都不会有精度损失,等值匹配就能正常工作。 - 如果无法修改字段类型:可以采用精度容忍的查询方式,比如:
- 范围查询:
where(['between', 'value', $this->value - 0.005, $this->value + 0.005]),给数值留一个微小的误差范围 - 四舍五入后匹配:
where(['ROUND(value, 2)' => round($this->value, 2)]),注意这种方式可能会导致字段索引失效,查询性能下降,仅适合数据量不大的场景
- 范围查询:
内容的提问来源于stack exchange,提问作者Vishal Bareja
相关产品推荐
相关产品推荐

