10

Hibernate Criteria APIを使用して特定の値の合計を取得するクエリを作成しました。次に、その合計が特定の値以上の行に結果を制限できるようにする必要があります。

通常、これを行うためにSQLでHAVING句を使用しますが、CriteriaAPIは現時点ではそれをサポートしていないようです。

生のSQLでは、これが私が行う必要があることです。

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

私が考えた回避策の1つは、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の問題を解決するために使用できるその他の提案/回避策について、誰かが私に正しい方向を示すことができますか?

これは、上記の例で使用したCriteriaAPIコードです。

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

このアプローチの欠点は、それぞれの合計を 2 回計算することです。これは、関連するデータの量によってはパフォーマンスに悪影響を与える可能性があります。その場合、HAVING 句をサポートする HQL クエリを使用する必要があります。

于 2009-01-29T05:38:45.707 に答える
1

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

于 2009-08-14T02:31:13.910 に答える