10

我使用 Hibernate Criteria API 编写了一个查询来获取特定值的总和,现在我需要能够将结果限制为总和大于或等于特定值的行。

通常我会在我的 SQL 中使用 HAVING 子句来执行此操作,但 Criteria API 目前似乎不支持它。

在原始 SQL 中,这是我需要它做的事情:

SELECT user_pk, sum(amount) as amountSum
FROM transaction
GROUP BY user_pk
HAVING amountSum >=50;

我想到的一种解决方法是在 FROM 子句中使用一个子查询来获取这个总和值,并使用一个外部查询来使用 WHERE 子句来限制它。

因此,在原始 SQL 中,它看起来像:

SELECT user_pk, amountSum
FROM (SELECT user_pk, sum(amount) as amountSum
      FROM transaction
      GROUP BY user_pk)
WHERE amountSum > 50;

谁能指出我如何使用 Criteria API 编写此代码的正确方向,或者我可以用来解决 HAVING 问题的任何其他建议/解决方法?

这是我为上述示例提供的 Criteria API 代码

DetachedCriteria criteria = DetachedCriteria.forClass(Transaction.class,"transaction");
criteria.setProjection(criteria.setProjection(Projections.projectionList().add(
        Projections.groupProperty("user.userPK").as("user_pk")).add(
            Projections.sum("transaction.amount").as("amountSum")));

谢谢!

4

3 回答 3

8

我不知道 Hibernate/NHibernate 在 FROM 子句中使用子查询的方法,但您可以在 WHERE 子句中使用它们。对于任何 Java/Hibernate 代码错误,我深表歉意,我更熟悉 C#/NHibernate。


DetachedCriteria subQuery = DetachedCriteria.forClass(Transaction.class);
subQuery.setProjection(Projections.sum("amount"));
subQuery.add(Expression.eqProperty("userPk", "tOuter.userPk"));

DetachedCriteria outerQuery = DetachedCriteria.forClass(Transaction.class, "tOuter");
outerQuery.setProjection(Projections.projectionList()
    .Add(Projections.sum("amount").as("sumAmount"))
    .Add(Projections.groupProperty("userPk").as("user_pk"));
outerQuery.add(Subqueries.le(50, subQuery));


此代码应产生类似于以下内容的 SQL:


SELECT tOuter.userPk as user_pk, sum(tOuter.amount) as sumAmount
FROM transaction tOuter
WHERE 50 <= (SELECT sum(amount) FROM transaction WHERE userPk = tOuter.userPk)
GROUP BY tOuter.userPk

这种方法的缺点是它计算每个总和两次,这可能会对性能产生不利影响,具体取决于所涉及的数据量 - 在这种情况下,您将需要使用支持 HAVING 子句的 HQL 查询。

于 2009-01-29T05:38:45.707 回答
2

HHH-1700 被标记为 HHH-1043 的副本,因此不会被修复。您会在HHH-1043上找到我的解决方案和解决方法,以及其他人的解决方案。

于 2010-02-04T09:25:12.180 回答
1

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1700

于 2009-08-14T02:31:13.910 回答