我使用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问题的任何其他建议/解决方法来编写此方法的正确方向吗?
这是我对上述示例的标准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")));
谢谢!
答案 0 :(得分: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查询子句。
答案 1 :(得分:2)
答案 2 :(得分:1)