次のようなデータがあります。
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);
この「GROUPBY式ではありません」エラーが発生する理由を知っている人はいますか?
私はここでトムから時間間隔で平均化を行うこの方法を選びました: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を使用して、テーブルの列の1つの名前である列の名前を変更しました。sampletimeの代わりに「tspan」という名前では機能しません。
ORA-00904: "TSPAN": invalid identifier
00904. 00000 - "%s: invalid identifier"
新しい列にsampletimeという名前を付け、GROUP BY句でsampletimeを使用すると、そのエラーはなくなり、SQLDeveloperでクエリが完全に実行されました。残念ながら、Javaから実行すると、サンプル時間ごとに複数の同一の行が返されました。Grrrr...。
解決策:以下で選択した解決策が機能しました。文字列を読みやすくするために、文字列を引用符とプラス記号で囲みました。
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 ";