使用jooq将COUNT值除以另一个值时的舍入问题

时间:2019-01-09 15:59:25

标签: java sql jooq

使用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,但没有成功。

还有其他人有类似的问题并且知道解决方案吗?

1 个答案:

答案 0 :(得分:1)

这里有两个问题,具体取决于您所使用的RDBMS:

1。整个投影表达式的类型

整个除法表达式的类型取决于左手边(股息)的类型,即SQLDataType.INTEGER。因此,不管您的RDBMS返回的是十进制数还是浮点数,jOOQ都将使用JDBC的ResultSet.getInt()方法来获取值,这将导致精度下降。因此,第一步是确保jOOQ将获取所需的数据类型。有几种方法可以做到这一点:

  1. COUNT(*)表达式使用强制类型转换:count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7)
  2. 对整个表达式使用强制转换: count(MYTABLE.ID).divide(7).cast(SQLDataType.DOUBLE)
  3. 在任何一个表达式上使用data type coercionexpr.coerce(SQLDataType.DOUBLE)

广播对生成的SQL有影响。数据类型强制没有。

2。您的RDBMS如何处理数据类型

在大多数RDBMS中,count(*)表达式产生一个整数类型,而除法的右手边(除数)也是一个整数,因此,结果最好的数据类型实际上是一个整数类型。我怀疑您应该通过doubleBigDecimal类型作为除数。

解决方案

那么理想的解决方案是将以上两个结合起来:

dsl.select(count(MYTABLE.ID).cast(SQLDataType.DOUBLE).divide(7.0))
   .from(MYTABLE)
   .fetch();