我使用Grails Criteria(类似于hibernate标准)从给定表中获取每个分区中获得最高分的学生列表。并且我只需要Name
, Division
和Grade
字段。
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')
}
}
我只得到Division
和Grade
,其他字段不包括在内。我需要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)
这是一个常见的聚合问题。所选字段必须出现在GROUP BY子句[*]中。正如我所看到的,您的Division列和Name列组合是无法比拟的,因此您需要以另一种方式进行操作。
我认为没有办法使用createCriteria得到答案,但我尝试了其他东西,请尝试一下:
def studentList = Student.executeQuery("from Student A where A.Grade in (select max(B.Grade) from Student as B group by B.Division)")
您可以尝试下面的查询。它工作得很顺利。
def studentDetails = Student.where {
grade == max(grade)}.property("name")).list().groupBy {"divison"}
为了避免@Gokul指出的问题,您可以尝试将name
放入max
子句:
def resultlt = Student.withCriteria() {
projections {
max 'name'
groupProperty 'divison'
max 'grade'
}
}
虽然我不确定这里的排序…