4

我正在使用Grails标准(类似于休眠标准)来获得学生在给定表格的每个分区中成绩最高的学生列表。我只想要Name,DivisionGrade字段。是否可以在Projections,Criteria,Grails中使用聚合函数和属性?

Name | Division | Grade | Std_id 
--------------------------------- 
AA1 | A  | 2  | 1 
AA2 | A  | 4  | 2 
BB1 | B  | 2  | 3 
BB2 | B  | 5  | 4 

我想要的结果是

Name | Division | Grade | 
-------------------------- 
AA2 | A  | 4  | 
BB2 | B  | 5  | 

如果我用以下标准

def criteria = Student.createCriteria() 
    def resultlt = criteria.list { 
     projections { 
      groupProperty('divison') 
      max('grade')    
     } 
    } 

我只拿到了DivisionGrade,不包括其他领域。我还需要Name字段。

如果我改变了标准(使用聚集函数和属性一起在突起)到

def criteria = Student.createCriteria() 
    def resultlt = criteria.list { 
     projections { 
      property('name') 
      groupProperty('divison') 
      max('grade') 

     } 
    } 

它提供以下错误..

ERROR: column "this_.name" must appear in the GROUP BY clause or be 
used in an aggregate function 
    Position: 63. Stacktrace follows: 
org.postgresql.util.PSQLException: ERROR: column "this_.name" must 
appear in the GROUP BY clause or be used in an aggregate function 
    Position: 63 
     at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryEx 
ecutorImpl.java:2161) 
     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutor 
Impl.java:1890) 
     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.ja 
va:255) 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Stat 
ement.java:559) 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(Abstract 
Jdbc2Statement.java:417) 
     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc 
2Statement.java:302) 

回答

4

这是一个常见聚合问题。所选字段必须出现在GROUP BY子句[*]中。正如我可以看到您的分区列和名称列组合是无与伦比的,所以您需要以另一种方式来完成。我认为你需要对上述条件进行子查询。

0

为了避免该问题所指出的@Gokul你可以尝试把你namemax条款:

def resultlt = Student.withCriteria() { 
     projections { 
      max 'name' 
      groupProperty 'divison' 
      max 'grade'     
     } 
    } 

虽然我不知道这里的分选..

+0

只有当你想选择的列是'String'类型时,这个解决方案才会起作用。如果列是'numeric(int,long,float)'类型,它将不会工作。 –

+0

为什么?如果可以应用聚合函数,那么它将起作用 – injecteer

+0

我刚刚测试了它,它给出了错误的值。你也可以测试它。 –

1

我觉得这是没有办法得到回答用个createCriteria但我想别的事情,请您尝试一下:

def studentList = Student.executeQuery("from Student A where A.Grade in (select max(B.Grade) from Student as B group by B.Division)") 
+0

外部选择中缺少'distinct' – injecteer

+0

您想要所有细节,因此不需要使用不同的细节。 –

1

你可以试用一下下面query.It工程进展顺利。

def studentDetails = Student.where { 
grade == max(grade)}.property("name")).list().groupBy {"divison"} 
相关问题