SQLDeveloper 运行查询,但从休眠中获得“ORA-00979: Not a Group By expression”

Posted

技术标签:

【中文标题】SQLDeveloper 运行查询,但从休眠中获得“ORA-00979: Not a Group By expression”【英文标题】:SQLDeveloper runs query but getting a "ORA-00979: Not a Group By expression" from hibernate 【发布时间】:2012-11-16 22:16:42 【问题描述】:

我的数据看起来像这样:

  sensorid |  sampletime             |  correctedvalue   | qualityflag
-----------------------------------------------------------------------
  4472     | 27-OCT-10 00:00:00.123  |   3.75            | 0
  4472     | 27-OCT-10 00:00:01.324  |   3.85            | 0
  4472     | 27-OCT-10 00:00:02.123  |   3.92            | 0
  4472     | 27-OCT-10 00:00:03.324  |   4.05            | 0

还有一个在 Oracle SQL Developer 中运行良好的查询(它返回平均超过 15 秒的数据):

select sensorid,
    trunc(sampletime,'hh24') + 
    (trunc(to_char(sampletime,'mi')))/24/60 +
    (trunc(to_char(sampletime,'ss')/15)*15)/24/60/60 as tspan, 
    avg(correctedvalue),
    max(qualityflag)
from scalarsample
group by sensorid, 
    trunc(sampletime,'hh24') + 
    (trunc(to_char(sampletime,'mi')))/24/60 +
    (trunc(to_char(sampletime,'ss')/15)*15)/24/60/60
order by tspan

但是当我将它插入到我的 java 代码中时,我得到一个错误:

org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2223)
...
Caused by: java.sql.SQLSyntaxErrorException: ORA-00979: not a GROUP BY expression

at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:221)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:118)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:224)
...

我在 Jave 中使用的实际查询字符串看起来更像这样:

select sensorid,
    trunc(sampletime,'hh24') + 
    (trunc(to_char(sampletime,'mi')))/24/60 +
    (trunc(to_char(sampletime,'ss')/?)*?)/24/60/60 as tspan, 
    avg(correctedvalue),
    max(qualityflag)
from scalarsample
where sampletime between ? and ?
    and sensorid = ?
group by sensorid, 
    trunc(sampletime,'hh24') + 
    (trunc(to_char(sampletime,'mi')))/24/60 +
    (trunc(to_char(sampletime,'ss')/?)*?)/24/60/60
order by tspan

并通过调用来设置参数:

SQLQuery q = session.createSQLQuery(queryString);
q.setInteger(0, averagingWindowInSeconds);
q.setInteger(1, averagingWindowInSeconds);
q.setTimestamp(2, dateFrom);
q.setTimestamp(3, dateTo);
q.setInteger(4, sensorId);
q.setInteger(5, averagingWindowInSeconds);
q.setInteger(6, averagingWindowInSeconds);
q.addEntity(ScalarSampleState.class);

有人知道为什么我会收到“不是 GROUP BY 表达式”错误吗?

我在这里从 Tom 那里学到了这种对时间间隔进行平均的方法: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4222062043865

编辑 它几乎似乎可以通过以下方式解决:

select sensorid,
    trunc(sampletime,'hh24') + 
    (trunc(to_char(sampletime,'mi')))/24/60 +
    (trunc(to_char(sampletime,'ss')/?)*?)/24/60/60 as sampletime, 
    avg(correctedvalue),
    max(qualityflag)
from scalarsample
where sampletime between ? and ?
    and sensorid = ?
group by sensorid, sampletime
order by sampletime

注意:我使用 sampletime 重命名了该列,它是表中某一列的名称。它不适用于名称“tspan”而不是采样时间:

ORA-00904: "TSPAN": invalid identifier
00904. 00000 -  "%s: invalid identifier"

当我命名新列 sampletime 并在 GROUP BY by 子句中使用 sampletime 时,该错误消失了,查询在 SQLDeveloper 中完美运行。不幸的是,当从 Java 运行时,它为每个采样时间返回了几个相同的行。呜呜呜……

解决方案: 起作用的是下面选择的解决方案——我去掉了字符串周围的引号和加号,使其在此处更具可读性:

SELECT
    sensorid, 
    TRUNC( sampletime, hh24) +
    (TRUNC(to_char(sampletime,'mi')))/24/60 +
    (TRUNC(to_char(sampletime,'ss')//averagingWindowInSeconds )*averagingWindowInSeconds)/24/60/60 as sampletime,
    AVG( correctedvalue) as correctedvalue, 
    MAX(qualityflag)
FROM scalarsample
WHERE 
    sampletime BETWEEN ? AND ?
    AND sensorid = ?
GROUP BY sensorid,
    TRUNC( sampletime, hh24) +
    (TRUNC(to_char(sampletime,'mi')))/24/60 +
    (TRUNC(to_char(sampletime,'ss')//averagingWindowInSeconds 
ORDER BY sampletime ";  

【问题讨论】:

Это вседа так бывает не очень хороший вопрос. 如果我没记错的话,ORDER BY 应该只列出 GROUP BY 表达式。尝试 ORDER BY 2 或省略 ORDER BY 并切换前两个 SELECT 列。 抱歉,找到了this。也许这意味着应该做ORDER by tspan, sensorid 我会同意的,但它在 SQL Developer 中运行良好。它与 Hibernate 有关,但如果是对象映射问题,错误消息就没有意义。 不需要积分。很高兴你找到它。 【参考方案1】:

看起来 JDBC 驱动程序正在为每个“?”创建一个唯一的绑定变量名。不幸的是,在 Oracle 中,group by 子句必须逐个字符地匹配 select 子句,正因为如此,它不匹配。 我在 Oracle 中用您的数据模拟了一个表,并使用动态 SQL 和绑定变量运行了一些测试查询。 首先,使用顺序命名的绑定变量:

SQL> l
  1  declare
  2  cur sys_refcursor;
  3  begin
  4  open cur for 'select sensorid, ' ||
  5  '    trunc(sampletime,''hh24'') +  ' ||
  6  '    (trunc(to_char(sampletime,''mi'')))/24/60 + ' ||
  7  '    (trunc(to_char(sampletime,''ss'')/:b1)*:b2)/24/60/60 as tspan,  ' ||
  8  '    avg(correctedvalue), ' ||
  9  '    max(qualityflag) ' ||
 10  'from scalarsample ' ||
 11  'where sampletime between DATE ''2010-10-27'' and DATE ''2010-10-28'' ' ||
 12  '    and sensorid = 4472 ' ||
 13  'group by sensorid,  ' ||
 14  '    trunc(sampletime,''hh24'') +  ' ||
 15  '    (trunc(to_char(sampletime,''mi'')))/24/60 + ' ||
 16  '    (trunc(to_char(sampletime,''ss'')/:b3)*:b4)/24/60/60 ' ||
 17  'order by tspan'
 18  using 15, 15, 15, 15;
 19  close cur;
 20* end;

结果:

SQL> @test
declare
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression
ORA-06512: at line 4

其次,使用同名绑定变量:

SQL> l
  1  declare
  2  cur sys_refcursor;
  3  begin
  4  open cur for 'select sensorid, ' ||
  5  '    trunc(sampletime,''hh24'') +  ' ||
  6  '    (trunc(to_char(sampletime,''mi'')))/24/60 + ' ||
  7  '    (trunc(to_char(sampletime,''ss'')/:b1)*:b1)/24/60/60 as tspan,  ' ||
  8  '    avg(correctedvalue), ' ||
  9  '    max(qualityflag) ' ||
 10  'from scalarsample ' ||
 11  'where sampletime between DATE ''2010-10-27'' and DATE ''2010-10-28'' ' ||
 12  '    and sensorid = 4472 ' ||
 13  'group by sensorid,  ' ||
 14  '    trunc(sampletime,''hh24'') +  ' ||
 15  '    (trunc(to_char(sampletime,''mi'')))/24/60 + ' ||
 16  '    (trunc(to_char(sampletime,''ss'')/:b1)*:b1)/24/60/60 ' ||
 17  'order by tspan'
 18  using 15, 15, 15, 15;
 19  close cur;
 20* end;

结果:

SQL> @test
PL/SQL procedure successfully completed.

因此,请尝试将您的 averagingWindowInSeconds 值连接到您的查询,而不是使用这 4 个绑定变量。

【讨论】:

哇,这真的很酷。我似乎记得以前遇到过绑定变量的问题。我原以为只有在使用带有命名查询的 Query 对象时才会发生这种情况,而上次我使用使用查询字符串创建的 SQLQuery 对象来解决它。上面的评论有助于解决问题,显然是通过将绑定变量从 group-by 短语中取出 感谢您的见解! 这行得通。感谢您提供的出色示例和对原因的非常清晰的解释!我将 averagingWindowInSeconds 连接到 group by 子句中,现在可以正常工作了。

以上是关于SQLDeveloper 运行查询,但从休眠中获得“ORA-00979: Not a Group By expression”的主要内容,如果未能解决你的问题,请参考以下文章

在 PL/SQL Developer 中运行的日期查询显示时间,但在 Oracle SQL Developer 中不显示

在多用户环境中使用休眠更新运行平衡

SQL 无效列错误。在sql developer中工作,在java中给出错误

在 mysql 中模拟休眠查询

Python的请求库超时但从浏览器获得响应

Hibernate 删除记录惨遭失败