错误:列“this_.phitorsionangle”必须出现在 GROUP BY 子句中或在聚合函数中使用

发布于 2024-10-11 10:25:59 字数 5308 浏览 3 评论 0原文

我在执行 sql 查询时遇到了一些问题。我正在使用 Hibernate Criteria 来构建查询。我通过按一定间隔(binSize)舍入值然后对它们进行分组来从数据库创建一些容器。当我直接在 SQL 中使用查询尝试它时,这非常有效:

SELECT floor(phiTorsionAngle / 2) * 2 as phiTorsionAngleBin, 
       floor(psiTorsionAngle / 2) * 2 as psiTorsionAngleBin, 
       floor(phiTorsionAngle / 2) + 180 as phiTorsionAngleBinIndex, 
       floor(psiTorsionAngle / 2) + 180 as psiTorsionAngleBinIndex, 
       count(*) as numberOfResidues
FROM residue

WHERE phitorsionangle IS NOT NULL
  AND psitorsionangle IS NOT NULL

GROUP BY phiTorsionAngleBin, psiTorsionAngleBin

但是当我使用 Hibernate Criteria 尝试它时,它失败了。这是构建查询的代码:

ScrollableResults phiPsiBins = createCriteria()
.setProjection(Projections.projectionList()
       .add(Projections.sqlGroupProjection(
         "floor(phiTorsionAngle / " + binSize + ") * " + binSize + " as phiTorsionAngleBin, " +
         "floor(psiTorsionAngle / " + binSize + ") * " + binSize + " as psiTorsionAngleBin, " +         
         "floor(phiTorsionAngle / " + binSize + ") + 180 as phiTorsionAngleBinIndex, " +
         "floor(psiTorsionAngle / " + binSize + ") + 180 as psiTorsionAngleBinIndex, " + 
         "count(*) as numberOfResidues",
         "phiTorsionAngleBin, psiTorsionAngleBin",
         new String[] {"phiTorsionAngleBin", "psiTorsionAngleBin", "phiTorsionAngleBinIndex", "psiTorsionAngleBinIndex", "numberOfResidues"},
         new Type[] {Hibernate.DOUBLE, Hibernate.DOUBLE, Hibernate.INTEGER, Hibernate.INTEGER, Hibernate.INTEGER})))
.add(Restrictions.isNotNull("phiTorsionAngle"))
.add(Restrictions.isNotNull("psiTorsionAngle"))
.setResultTransformer(Transformers.aliasToBean(PhiPsiBinResult.class))
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);

这是我收到的错误消息,下面有完整的堆栈跟踪:

ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function

WARN  2011-01-11 16:13:43,047 main JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42803
ERROR 2011-01-11 16:13:43,047 main JDBCExceptionReporter:101 - ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function
  Position: 143
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query using scroll
 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
 at org.hibernate.loader.Loader.scroll(Loader.java:2340)
 at org.hibernate.loader.criteria.CriteriaLoader.scroll(CriteriaLoader.java:113)
 at org.hibernate.impl.SessionImpl.scroll(SessionImpl.java:1561)
 at org.hibernate.impl.CriteriaImpl.scroll(CriteriaImpl.java:320)
 at nl.ru.cmbi.pdbeter.core.controller.DAO.ResidueDAO.getPhiPsiBinSet(ResidueDAO.java:236)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:616)
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 at $Proxy27.getPhiPsiBinSet(Unknown Source)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsFunctions.makeRamachandranPlot(StatisticsFunctions.java:26)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.start(StatisticsMain.java:39)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.main(StatisticsMain.java:33)
Caused by: org.postgresql.util.PSQLException: ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function
  Position: 143
 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
 at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
 at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
 at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
 at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
 at org.hibernate.loader.Loader.scroll(Loader.java:2305)
 ... 18 more

我尝试将 phiTorsionAngle 和 psiTorsionAngle 添加到 GROUP BY,这似乎有效,但没有意义这样做。我不想按 phiTorsionAngle 的每个可能值进行分组,我想按整个 bin 进行分组,可能包含很多不同的 phiTorsionAngle 值。为什么它会给我这个错误以及如何解决它?

更新:我实际上并没有尝试让查询运行直到它完成,并且我收到了 Java 堆空间不足错误,因为它尝试加载大约 1900 万个条目,因此将 phiTorsionAngle 和 psiTorsionAngle 添加到分组中是现在完全不可能了:)

I'm having some trouble with an sql query. I'm using Hibernate Criteria to build the query. I create some bins from a database by rounding the values with certain intervals (the binSize) and then grouping them. This works great when I try it directly in SQL with the query:

SELECT floor(phiTorsionAngle / 2) * 2 as phiTorsionAngleBin, 
       floor(psiTorsionAngle / 2) * 2 as psiTorsionAngleBin, 
       floor(phiTorsionAngle / 2) + 180 as phiTorsionAngleBinIndex, 
       floor(psiTorsionAngle / 2) + 180 as psiTorsionAngleBinIndex, 
       count(*) as numberOfResidues
FROM residue

WHERE phitorsionangle IS NOT NULL
  AND psitorsionangle IS NOT NULL

GROUP BY phiTorsionAngleBin, psiTorsionAngleBin

But when I try it with Hibernate Criteria it fails. This is the code to build the query:

ScrollableResults phiPsiBins = createCriteria()
.setProjection(Projections.projectionList()
       .add(Projections.sqlGroupProjection(
         "floor(phiTorsionAngle / " + binSize + ") * " + binSize + " as phiTorsionAngleBin, " +
         "floor(psiTorsionAngle / " + binSize + ") * " + binSize + " as psiTorsionAngleBin, " +         
         "floor(phiTorsionAngle / " + binSize + ") + 180 as phiTorsionAngleBinIndex, " +
         "floor(psiTorsionAngle / " + binSize + ") + 180 as psiTorsionAngleBinIndex, " + 
         "count(*) as numberOfResidues",
         "phiTorsionAngleBin, psiTorsionAngleBin",
         new String[] {"phiTorsionAngleBin", "psiTorsionAngleBin", "phiTorsionAngleBinIndex", "psiTorsionAngleBinIndex", "numberOfResidues"},
         new Type[] {Hibernate.DOUBLE, Hibernate.DOUBLE, Hibernate.INTEGER, Hibernate.INTEGER, Hibernate.INTEGER})))
.add(Restrictions.isNotNull("phiTorsionAngle"))
.add(Restrictions.isNotNull("psiTorsionAngle"))
.setResultTransformer(Transformers.aliasToBean(PhiPsiBinResult.class))
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);

This is the error message I'm getting, with the full stacktrace below it:

ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function

WARN  2011-01-11 16:13:43,047 main JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42803
ERROR 2011-01-11 16:13:43,047 main JDBCExceptionReporter:101 - ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function
  Position: 143
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query using scroll
 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
 at org.hibernate.loader.Loader.scroll(Loader.java:2340)
 at org.hibernate.loader.criteria.CriteriaLoader.scroll(CriteriaLoader.java:113)
 at org.hibernate.impl.SessionImpl.scroll(SessionImpl.java:1561)
 at org.hibernate.impl.CriteriaImpl.scroll(CriteriaImpl.java:320)
 at nl.ru.cmbi.pdbeter.core.controller.DAO.ResidueDAO.getPhiPsiBinSet(ResidueDAO.java:236)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:616)
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 at $Proxy27.getPhiPsiBinSet(Unknown Source)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsFunctions.makeRamachandranPlot(StatisticsFunctions.java:26)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.start(StatisticsMain.java:39)
 at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.main(StatisticsMain.java:33)
Caused by: org.postgresql.util.PSQLException: ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function
  Position: 143
 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
 at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
 at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
 at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
 at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
 at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
 at org.hibernate.loader.Loader.scroll(Loader.java:2305)
 ... 18 more

I tried adding the phiTorsionAngle and psiTorsionAngle to the GROUP BY, and this seems to work, but it makes no sense to do that. I don't want to group by every possible value for phiTorsionAngle, I want to group by the entire bin, probably containing a lot of different values for phiTorsionAngle. Why does it give me this error and how do I work around it?

UPDATE: I didn't actually try to let the query run until it was finished yet, and I got a Java out of heap space error, because it tried to load about 19 million entries, so adding the phiTorsionAngle and psiTorsionAngle to the grouping is now entirely out of the question :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑咖 2024-10-18 10:25:59
SELECT  phiTorsionAngleHalfFloor * 2 as phiTorsionAngleBin, 
        psiTorsionAngleHalfFloor * 2 as psiTorsionAngleBin, 
        phiTorsionAngleHalfFloor + 180 as phiTorsionAngleBinIndex, 
        psiTorsionAngleHalfFloor + 180 as psiTorsionAngleBinIndex, 
        numberOfResidues
FROM    (
        SELECT  FLOOR(phiTorsionAngleHalf / 2) AS phiTorsionAngleHalfFloor,
                FLOOR(psiTorsionAngleHalf / 2) AS psiTorsionAngleHalfFloor,
                COUNT(*) AS numberOfResidues
        FROM    residue
        WHERE   phitorsionangle IS NOT NULL
                AND psitorsionangle IS NOT NULL
        GROUP BY
                phiTorsionAngleHalfFloor, psiTorsionAngleHalfFloor
        ) q
SELECT  phiTorsionAngleHalfFloor * 2 as phiTorsionAngleBin, 
        psiTorsionAngleHalfFloor * 2 as psiTorsionAngleBin, 
        phiTorsionAngleHalfFloor + 180 as phiTorsionAngleBinIndex, 
        psiTorsionAngleHalfFloor + 180 as psiTorsionAngleBinIndex, 
        numberOfResidues
FROM    (
        SELECT  FLOOR(phiTorsionAngleHalf / 2) AS phiTorsionAngleHalfFloor,
                FLOOR(psiTorsionAngleHalf / 2) AS psiTorsionAngleHalfFloor,
                COUNT(*) AS numberOfResidues
        FROM    residue
        WHERE   phitorsionangle IS NOT NULL
                AND psitorsionangle IS NOT NULL
        GROUP BY
                phiTorsionAngleHalfFloor, psiTorsionAngleHalfFloor
        ) q
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文