使用jOOQ进行COUNT值除法运算时的精度丢失问题求助
解决jOOQ中COUNT除法返回整数而非小数的问题
这问题我之前踩过坑,本质是jOOQ对COUNT()这类整数型聚合函数的除法处理逻辑和原生SQL不一样~
问题原因
原生SQL里,当你执行SELECT (COUNT(ID)/7) FROM myTable时,数据库会自动做隐式类型转换:把整数类型的COUNT结果和整数7运算时,自动提升为浮点/小数类型,所以能得到带四位小数的结果。
但jOOQ的count()方法返回的是Field<Long>类型(整数型),当你调用.divide(7)时,7默认被当作整数处理,jOOQ会执行整数除法,直接舍去小数部分,所以得到1而不是1.7143。而SUM如果本身是数值类型(比如DECIMAL),除法时会保留小数,所以你用SUM的同类代码没问题。
解决方案
这里给你几个可行的处理方式:
1. 将除数转为浮点/小数类型
把整数7改成浮点型的7.0,或者显式指定小数类型,让jOOQ执行浮点除法:
dsl.select(count(MYTABLE.ID).divide(DSL.val(7.0))) .from(MYTABLE) .fetch();
或者更严谨地指定SQL数据类型:
dsl.select(count(MYTABLE.ID).divide(DSL.inline(7, SQLDataType.DOUBLE))) .from(MYTABLE) .fetch();
2. 将COUNT结果转为小数类型
先把count()的结果通过cast()转成DOUBLE或DECIMAL类型,再做除法:
dsl.select(count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7)) .from(MYTABLE) .fetch();
3. 直接使用原生SQL片段
如果你更习惯原生SQL的写法,可以用DSL.field()直接构造原生表达式:
dsl.select(DSL.field("COUNT({0}) / 7", SQLDataType.DOUBLE, MYTABLE.ID)) .from(MYTABLE) .fetch();
补充说明
你尝试的.round()方法无效,是因为它是对已有小数结果做四舍五入,但整数除法得到的本身就是整数,再round也还是整数。必须先确保除法运算为浮点/小数类型,再根据需要使用.round()调整小数位数。
内容的提问来源于stack exchange,提问作者androidUser1993
相关产品推荐
相关产品推荐

