JPA JPQL:使用COUNT,GROUP BY和ORDER BY选择NEW

时间:2014-08-25 00:53:17

标签: java select jpa aggregate-functions jpql

有2个表/实体:AppleTreeApples。一棵苹果树产生0 ... n个苹果。每个apple都是第二个表的实体/行,并引用生成它的苹果树(ManyToOne)。

我希望在最高产的苹果树上制作一份“高分”报告。它应按COUNT列按降序排序:

APPLE TREE | COUNT(A)
---------------------
10304      | 1000
72020      | 952
31167      | 800

为了处理这些结果,我创建了一个非实体bean,它结合了AppleTree对象和long值(对于COUNT):

// constructor
public AppleStats (AppleTree at, long howManyApples) { ... }

我想使用JPQL获取此组合类型的行。我的方法基于SELECT NEW语法:

SELECT NEW foo.bar.AppleStats ( a.appleTree, COUNT(a) AS c )
FROM Apples a
GROUP BY a.appleTree
ORDER BY c DESC

不幸的是,它会产生很多错误消息。我认为一个问题是COUNT值的列别名。我使用它,因为我想按这个聚合值排序。这意味着我使用“COUNT(a)AS c”还是“COUNT(a)c”没有区别。它说参数没有用逗号分隔。而且,“表达式无效,这意味着它不遵循JPQL语法”。最后它说没有找到与参数类型匹配的构造函数。“

有没有办法获取AppleStats结果行?或者我是否必须回归本地查询?

1 个答案:

答案 0 :(得分:4)

尝试此查询:

SELECT NEW foo.bar.AppleStats(a.appleTree, COUNT(a.appleTree))
FROM Apples a
GROUP BY a.appleTree
ORDER BY COUNT(a.appleTree) DESC

不幸的是我现在没有JPA平台来测试它,但上面应该修复原始查询的语法问题。并且不要担心COUNT()聚合函数出现两次这一事实,这是编写查询时非常常见的习惯用法,任何不错的优化器都应该能够处理它并只执行一次操作。