【问题标题】:Is it possible to use aggregate functions and property in Projections, Criteria, Grails?是否可以在 Projections、Criteria、Grails 中使用聚合函数和属性?
【发布时间】:2016-09-16 02:49:29
【问题描述】:

我正在使用 Grails Criteria(类似于 hibernate 标准)从给定表中获取在每个部门中获得最高成绩的学生列表。我只想要NameDivisionGrade 字段。

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)

【问题讨论】:

    标签: hibernate grails criteria hibernate-criteria nhibernate-projections


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我认为使用 createCriteria 无法获得答案,但我尝试了其他方法,请尝试:

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

      【讨论】:

      • 外部选择中缺少distinct
      • 您需要所有详细信息,因此无需使用 distinct。
      【解决方案3】:

      您可以尝试以下查询。它运行顺利。

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

      【讨论】:

        【解决方案4】:

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

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

        虽然我不确定在这里排序..

        【讨论】:

        • 只有当您要选择的列是String 类型时,此解决方案才有效。如果列是numeric(int, long, float) 类型,它将不起作用。
        • 为什么?如果可以应用聚合函数,它将适用于任何类型
        • 我刚刚测试了它,它给出了错误的值。你也可以测试它。
        • 你必须更清楚。 “将不起作用”意味着错误
        • 例如-如果您想选择与具有max('grade') 的行关联的列age,并按照您在age 列所在的投影中添加max('age') 的建议numeric 类型,查询将返回正确的 max grade 以及错误的 age 值。它还将在 age 列上应用 max 函数。因此,如果max grade is 10age is 12 相关联,并且另一行具有age value 20,这是给定表的最大年龄,它将返回correct max grade as 10wrong age value i.e 20
        猜你喜欢
        • 2013-10-10
        • 2021-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-05
        • 2020-09-02
        • 1970-01-01
        相关资源
        最近更新 更多