2015-05-27 135 views
1

考虑以下的假设模型的GROUPBY子句实体:包括在CriteriaBuilder查询

@Entity 
class Parent{ 

    Integer number; 
    Child1 child1; 
    Child2 child2; 
    String description; 
} 

@Entity 
class Child1{ 
    Integer id; 
} 

@Entity 
class Child2{ 
    Integer id; 
} 

我建立一个查询,就好比Parentnumber聚合函数,但我也想显示child1child2 ,所以我将它们包含在标准构建器中的group by子句中。对于其他一些随机原因,我正在创建一个Tuple查询。

CriteriaQuery<Tuple> cq = cb.createTupleQuery(); 
Root<Parent> root = cq.from(Parent.class); 
cq.select(cb.tuple(root.get("description"), 
        root.get("child1") 
        cb.count(root.get("number"))); 

cq.groupBy(root.get("description"), 
      root.get("child1"))); 

当我执行此查询,我得到的错误:“child1.id包括在SELECT,但不包括一组由clasue中,而不是聚合函数的一部分。”每当我从实体Parent中选择不是实体本身的字段时,我没有任何问题。只要我尝试从类Parent中选择一个本身是实体的字段,即使将它包含在group by子句中,我也会遇到这种麻烦。我甚至尝试没有运气这样做:

cq.groupBy(root.get("description"), 
      root.get("child1").get("id"))); 

我怎样才能创建一个CriteriaQuery,做什么,我要怎么办?有没有解决这个问题的方法?

回答

0

我们必须对表中的所有字段使用聚合函数,除了执行group by的字段之外。 因此,对于您的情况,您只能使用以下功能从实体中选择值。

AVG() - Returns the average value. 
COUNT() - Returns the number of rows. 
FIRST() - Returns the first value. 
LAST() - Returns the last value. 
MAX() - Returns the largest value. 
MIN() - Returns the smallest value. 
SUM() - Returns the sum. 

您不能groupby编号,并选择child1没有聚合函数。 希望这有助于。

+0

我认为你可以由多个字段组成。 –

+0

@JadieldeArmas绝对我们可以groupby超过一个领域。让我们说你groupby A,B,C然后你可以选择没有集合函数的A,B和C,但对于其他字段你必须使用集合函数。 – Harshit

0

为了做到这一点,显然需要一个显式连接,以便当条件查询被转换为JPA时,正确的字段被识别为存在。我做到这一点的方式如下:

CriteriaQuery<Tuple> cq = cb.createTupleQuery(); 
Root<Parent> root = cq.from(Parent.class); 
Join<Parent, Child1> child1Join = root.join("child1"); 

cq.select(cb.tuple(root.get("description"), 
        child1Join.get("id"), 
        cb.count(root.get("number"))); 

cq.groupBy(root.get("description"), 
      child1Join.get("id")));