Laravel查询MySQL浮点列时where方法结果异常,whereRaw正常的原因
浮点数字段查询差异的原因解析
这个问题的核心在于MySQL float类型的精度特性,以及ORM框架参数绑定和原生SQL在类型处理上的差异:
- float类型的精度限制:MySQL的float是单精度浮点数,无法精确存储像0.3这样的十进制小数,实际存储的是一个接近0.3的二进制近似值(比如
0.29999998211860657)。 - 原生SQL的类型匹配:使用
whereRaw("odd > 0.3")时,MySQL会自动将SQL语句中的0.3解析为float类型(与字段类型一致),此时比较的是两个同精度的浮点数近似值,逻辑符合预期。 - ORM参数绑定的类型转换:当使用
$query->where("odd", ">", 0.3)时,ORM框架会将PHP中的0.3以双精度浮点数(double)的类型绑定到查询中。MySQL执行查询时,会把float类型的odd字段值隐式转换为double类型,再和double类型的0.3(其近似值为0.30000000000000004)进行比较。由于两种精度的近似值存在细微差异,导致原本在float精度下应该被判定为小于0.3的值,在double精度的比较中被错误地判定为大于0.3,最终出现在查询结果里。
如果要避免这种问题,除了使用whereRaw,还可以考虑将字段类型改为decimal(精确小数类型),或者在ORM绑定参数时显式指定类型为float。
内容的提问来源于stack exchange,提问作者wurhang
相关产品推荐
相关产品推荐

