我在使用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到分组现在完全不可能:)
答案 0 :(得分:1)
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