我有看起来像这样的数据:
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 表达式”错误吗?
我在这里从汤姆那里得到了这种在时间间隔内进行平均的方法: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 ";