2009-01-21 107 views
10

我已經使用Hibernate Criteria API編寫了一個查詢來獲取特定值的總和,現在我需要能夠將結果限制爲大於或等於一個特定的價值。Hibernate Criteria API - HAVING子句解決方法

正常情況下,我會在我的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; 

任何人都可以點我在正確的方向,我怎麼能寫這個使用標準的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"))); 

謝謝!

回答

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查詢。

2

HHH-1700被標記爲HHH-1043的副本,並且因此將不被固定。您可以在HHH-1043上找到我的解決方案和解決方法以及其他人員。

+0

這是7年前,仍然沒有修補內部休眠,我需要應用修補程序的版本4.3.6或更新,但代碼已被改變太多,我不清楚如何做到這一點。任何人有這個補丁更新? – 2017-02-10 14:48:46