3

私はjunitを書くためにHSQLDBを使用しています。私のクエリは次のようなものです:

String queryStr = "from ManualUrlBatchModel where status IN(:status) group by batchUser order by creationTime";
        Query query = getSession(requestType).createQuery(queryStr);
        query.setParameterList("status", status);

特定のステータスでユーザーごとに 1 つのバッチを取得しています (作成時の FIFO 順序によって異なります)。

エンド ツー エンドのテストでは正常に動作しますが、junit の書き込み中に失敗します。

例外は言う:

Caused by: java.sql.SQLException: Not in aggregate function or group by clause: org.hsqldb.Expression@164f8d4 in statement [select manualurlb0_.manual_url_batch_id as manual1_7_, manualurlb0_.creation_time as creation2_7_, manualurlb0_.modification_time as modifica3_7_, manualurlb0_.attribute_list as attribute4_7_, manualurlb0_.batch_name as batch5_7_, manualurlb0_.batch_user as batch6_7_, manualurlb0_.input_s3_key as input7_7_, manualurlb0_.locale as locale7_, manualurlb0_.notify_when_complete as notify9_7_, manualurlb0_.output_s3_key as output10_7_, manualurlb0_.processed_url_count as processed11_7_, manualurlb0_.s3_bucket as s12_7_, manualurlb0_.status as status7_, manualurlb0_.submitted_url_count as submitted14_7_, manualurlb0_.total_url_count as total15_7_ from csi_manual_url_batch manualurlb0_ where manualurlb0_.status in (? , ?) group by manualurlb0_.batch_user order by manualurlb0_.creation_time]
    [junit]     at org.hsqldb.jdbc.Util.throwError(Unknown Source)
    [junit]     at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
    [junit]     at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
    [junit]     at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
    [junit]     at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:452)
    [junit]     at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
    [junit]     at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1573)
    [junit]     at org.hibernate.loader.Loader.doQuery(Loader.java:696)
    [junit]     at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    [junit]     at org.hibernate.loader.Loader.doList(Loader.java:2228)

私はネット上でいくつかのものを見つけました:

  1. group by が文字列に基づいていない場合、GROUP BY は HSQLDB で機能しません。
  2. GROUP BY は、私が使用した方法では機能しません (select * .... group by COL1)。

人々は以前にこの問題に直面していたと思いますが、そのときあなたたちは何をしましたか (junits を書かないことを除けば :))? どんな助けでも大歓迎です。

4

2 に答える 2

7

標準 SQL では、group by 句には、集計関数である値を除く、選択されたすべての値を含める必要があります。

select a, b, c, d, sum(e) from table group by a -- INVALID
select a, b, c, d, sum(e) from table group by a, b  -- INVALID
select a, b, c, d, sum(e) from table group by a, b, c  -- INVALID
select a, b, c, d, sum(e) from table group by a, b, c, d -- VALID

したがって、Hibernate によって生成されたクエリは無効であり、知る限り、HQL クエリによるグループを機能させる唯一の方法は、明示的に選択するすべてのスカラー列をリストすることです ( https://hibernate.onjira.com/browse/HHHを参照)。 -1615 ):

 select m.foo, m.bar, m.creationTime, m.batchUser  
 from ManualUrlBatchModel m 
 where m.status IN(:status) 
 group by m.foo, m.bar, m.creationTime, m.batchUser 
 order by m.creationTime

元のクエリが MySQL で機能する場合、それは MySQL が SQL 標準を尊重しておらず、group by選択されたすべての列をリストしないクエリを許可しているためです。この「機能」に依存せず、テストと本番環境で同じデータベースを使用し、MySQL の代わりに PostgreSQL を使用することをお勧めします。

于 2012-12-25T10:20:25.583 に答える
1

グループ化したくないすべての選択値を集約することもできます。

例えばselect a, sum(b), sum(c), sum(d), sum(e) from table group by a; -- VALID

于 2016-04-13T09:58:26.770 に答える