【问题标题】:Does the JPQL avg aggregate function work with Integers?JPQL avg 聚合函数是否适用于整数?
【发布时间】:2011-02-16 23:53:56
【问题描述】:

我有一个名为 Surgery 的 JPA 2 实体。它有一个名为 transfusionUnits 的成员,它是一个 整数

数据库中有两个条目。执行这条 JPQL 语句:

Select s.transfusionUnits from Surgery s

产生预期的结果:

2
3

以下语句产生 5 的预期答案:

Select sum(s.transfusionUnits) from Surgery s

我希望以下语句的答案是 2.5,但它会返回 2.0

Select avg(s.transfusionUnits) from Surgery s

如果我在不同的 (Float) 成员上执行语句,结果是正确的。关于为什么会发生这种情况的任何想法?我需要在 JPQL 中进行某种类型的演员吗?这甚至可能吗?当然,我在这里遗漏了一些琐碎的事情。

【问题讨论】:

    标签: java orm jpa jpql jpa-2.0


    【解决方案1】:

    首先,让我总结一下 JPA 2.0 规范对 AVG 的规定(完整内容请参见 4.8.5 SELECT 子句中的聚合函数部分)

    AVG 函数将状态字段路径表达式作为参数,并计算组中状态字段的平均值。 state 字段必须是数字,结果以 Double 形式返回。

    所以,在第一次阅读之后,我期待以下 sn-p 通过:

    Query q = em.createQuery("select avg(s.transfusionUnits) from Surgery s");
    Double actual = (Double) q.getSingleResult();
    assertEquals(2.5d, actual.doubleValue());
    

    但事实并非如此,我得到了2.0 作为结果(一个 Double,但不是预期的结果)。

    所以我查看了数据库级别,发现 SQL 查询实际上没有返回 2.5。事实上,这就是我的数据库文档中关于 AVG 的内容:

    平均(平均值)值。如果未选择任何行,则结果为 NULL。只允许在 select 语句中使用聚合。 返回值与参数的数据类型相同

    我的期望太高了。 JPA 会以 Double 形式返回结果,但它不会产生任何魔力。如果查询没有返回具有所需精度的结果,您将无法在 Java 级别获得它。

    因此,在不更改 transfusionUnits 的类型的情况下,我必须运行这个本机查询才能让事情正常运行:

    Query q = em.createNativeQuery("SELECT AVG(CAST(s.transfusionUnits as double)) from Surgery s");
    Double actual = (Double) q.getSingleResult();
    assertEquals(2.5d, actual.doubleValue());
    

    更新:似乎某些数据库(例如 MySQL)在 INT 列上使用 AVG 时确实返回了一个带小数部分的值(这是有道理的,无论我记录的数据库行为如何)此处使用)。对于其他数据库,可以处理上述演员表 在“方言”中(例如,Hibernate 参见 HHH-5173)以避免使用 JPQL 时数据库之间的可移植性问题。

    【讨论】:

      【解决方案2】:

      将平均场转换为两倍就可以了。不确定性能影响,但不应该是邪恶的:

      Select avg(s.transfusionUnits + 0.0) from Surgery s
      

      【讨论】:

      • 这对我不起作用,我得到的错误应该是 ) 而不是 + 号。
      • 使用 openjpa 为我工作,似乎它依赖于提供程序
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      相关资源
      最近更新 更多