使用SQL时,我可以运行一个简单的查询(例如下面的查询,没有问题),它返回的答案是小数点后4位:
SELECT(COUNT(ID)/7) FROM myTable;
如果上述计数返回值12,则工作台中返回的选择值为1.7143。
当我使用jooq进行此计算时,会发生我的问题:
dsl.select(count(MYTABLE.ID).divide(7).from(MYTABLE).fetch();
上面的代码给我返回的值为1,而我想要的值为1.7143。
我有类似的jooq代码行,它们使用SUM而不是COUNT,并且它们将值返回到小数点后4位,但是我无法找到一种方法来获取上述代码将值返回到小数点后4位。
我尝试使用.round
,但没有成功。
还有其他人有类似的问题并且知道解决方案吗?
答案 0 :(得分:1)
这里有两个问题,具体取决于您所使用的RDBMS:
整个除法表达式的类型取决于左手边(股息)的类型,即SQLDataType.INTEGER
。因此,不管您的RDBMS返回的是十进制数还是浮点数,jOOQ都将使用JDBC的ResultSet.getInt()
方法来获取值,这将导致精度下降。因此,第一步是确保jOOQ将获取所需的数据类型。有几种方法可以做到这一点:
COUNT(*)
表达式使用强制类型转换:count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7)
count(MYTABLE.ID).divide(7).cast(SQLDataType.DOUBLE)
expr.coerce(SQLDataType.DOUBLE)
广播对生成的SQL有影响。数据类型强制没有。
在大多数RDBMS中,count(*)
表达式产生一个整数类型,而除法的右手边(除数)也是一个整数,因此,结果最好的数据类型实际上是一个整数类型。我怀疑您应该通过double
或BigDecimal
类型作为除数。
那么理想的解决方案是将以上两个结合起来:
dsl.select(count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7.0))
.from(MYTABLE)
.fetch();