Hibernate 是否可以在投影、条件和Grails中使用聚合函数和属性?

Hibernate 是否可以在投影、条件和Grails中使用聚合函数和属性?,hibernate,grails,criteria,hibernate-criteria,nhibernate-projections,Hibernate,Grails,Criteria,Hibernate Criteria,Nhibernate Projections,我正在使用Grails标准(类似于hibernate标准)从给定的表中获得每个分区中得分最高的学生的列表。我只需要名称,部门和等级字段 Name | Division | Grade | Std_id --------------------------------- AA1 | A | 2 | 1 AA2 | A | 4 | 2 BB1 | B | 2 | 3 BB2 | B | 5 | 4

我正在使用Grails标准(类似于hibernate标准)从给定的表中获得每个分区中得分最高的学生的列表。我只需要
名称
部门
等级
字段

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')             
        }
    }
我只得到了
部门
等级
,其他字段不包括在内。我还需要
Name
字段

如果我将标准(在投影中一起使用聚合函数和属性)更改为

它给出了以下错误

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列的组合是不可比较的,所以您需要用另一种方式来实现它。我认为您需要对上述条件进行子查询。

为了避免@Gokul指出的问题,您可以尝试将您的
name
放入
max
子句中:

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

虽然我不确定这里的排序方法。

我认为使用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"}

仅当要选择的列为
String
类型时,此解决方案才有效。如果列为
numeric(int、long、float)
类型,则此解决方案无效。为什么?如果可以应用聚合函数,它将适用于任何类型。我刚刚测试了它,它给出了错误的值。你也可以测试它。你必须更清楚。“将不起作用”是指一个错误,例如,如果您想选择与具有
max('grade')
的行关联的
age列,并且按照您的建议,在
age('age')
列为
numeric
类型的投影中添加
max('age')
,查询将返回正确的
max grade
以及错误的
age
值。它还将在
age
列上应用max函数。因此,如果
最大等级为10
,其关联
年龄为12
,还有一行的
年龄值为20
,这是给定表中的最大年龄,它将
正确的最大等级返回为10
,年龄值为20
。外部选择中缺少
distinct
。您需要所有详细信息,因此无需使用distinct。
def studentDetails = Student.where {
grade == max(grade)}.property("name")).list().groupBy {"divison"}