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"} 
相關問題