3

我正在使用 HSQLDB 编写junits,我的查询是这样的:

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

我在给定状态下为每个用户检索一批(取决于创建时间 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 不能按照我使用的方式工作(选择 * .... 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 生成的查询无效,而 AFAIK,通过 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不列出每个选定列的查询。我建议不要依赖这个“特性”,在测试和生产中使用相同的数据库,并使用 PostgreSQL 而不是 MySQL。

于 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 回答