Orm JPQL子查询中的限制

Orm JPQL子查询中的限制,orm,jpa,jpa-2.0,jpql,Orm,Jpa,Jpa 2.0,Jpql,我想通过JPA2获得前100名产品的平均价格。查询应该是这样的(我的sql有点生疏): 但这根本不起作用。我也试过: select avg(p.price) from Product p where p.id = (select pj.id from Product pj order by pj.price desc limit 100) 这将一直工作到limit关键字 我读到JPQL中没有该限制 你知道怎么做吗?标准也可以 SELECT AVG(SELECT PRICE FR

我想通过JPA2获得前100名产品的平均价格。查询应该是这样的(我的sql有点生疏):

但这根本不起作用。我也试过:

select avg(p.price) from Product p where p.id = 
       (select pj.id from Product pj order by pj.price desc limit 100)
这将一直工作到limit关键字

我读到JPQL中没有该限制

你知道怎么做吗?标准也可以

SELECT AVG(SELECT PRICE FROM PRODUCT ORDER BY PRICE DESC LIMIT 100) 
有关JPQL限制的解决方法,请参阅此部分。

JPQL不支持“限制”。下面是使用CriteriaAPI的示例代码

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Double> criteriaQuery = builder.createQuery(Double.class);
Root<Product> productRoot = criteriaQuery.from(Product.class);
criteriaQuery.select(builder.avg(productRoot.get("price")));
criteriaQuery.orderBy(builder.desc(productRoot.get("price"));
Double average = (Double)entityManager.createQuery(criteriaQuery).setMaxResults(100).getSingleResult();
如果这不起作用,那么就必须执行两个查询——选择绝对有序的记录,然后对它们求平均值


否则,如果可移植性不是问题,可以使用单个查询来完成相同的操作,因为许多RDBMS支持限制从数据库获取结果的数量。

这不起作用。它只是给了我一个SQL异常,说它是一个无效的ORDERBY表达式。顺便说一下,我正在使用hsql。好的,这项工作将需要2个db查询,对吗?在您的问题中,您按价格和购买订购一个查询。你们的产品表上有采购栏吗?对不起,我弄错了,它应该总是按价格订购的。我已更正。已进行更改,请立即尝试。JPQL不允许在SELECT子句中的聚合中进行子查询。有些实现可能允许这样做,但如果这样做会失去可移植性好吧,我使用了两个查询。Hsql和H2似乎都不喜欢标准和Hsql,因为它同时使用avg()来使用order。是否可以使用Criteria API执行子查询?是的,有关Criteria API中的子查询,请参阅。但问题在于限制在JPA中获取子查询的结果。在hibernate中,可以通过query.setFetchSize(intFetchSize)完成。
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Double> criteriaQuery = builder.createQuery(Double.class);
Root<Product> productRoot = criteriaQuery.from(Product.class);
criteriaQuery.select(builder.avg(productRoot.get("price")));
criteriaQuery.orderBy(builder.desc(productRoot.get("price"));
Double average = (Double)entityManager.createQuery(criteriaQuery).setMaxResults(100).getSingleResult();
Double average = (Double)entityManager.createQuery("select avg(p.price) from Product p order by p.price").setMaxResults(100).getSingleResult();