2009-01-21 13 views
10

HAVING deyimi iş ya, şimdi bunun toplamı büyük veya eşittir satırlara sonucu kısıtlamak gerekiyor belirli bir değer. hazırda Kriterleri API - Belirli bir değerin bir toplamının kapmak için hazırda Kriterleri API kullanarak bir sorgu yazdım

Normalde bunu yapmak benim SQL bir HAVING yan tümcesi kullanırsınız, ancak Ölçüt API şu anda bunu destekleyecek gibi görünmüyor.

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

Bir iş çevresinde ben düşündüm bir alt sorguyu kullanmak bu toplamıdır değerini yakalar o FROM yan tümcesi ve bir dış sorgusu kullanmaktır: bu ham SQL

bunu yapmak gerekir budur bir WHERE yan tümcesi kullanarak kısıtlamak için.

Yani, ham SQL bunun gibi bir şey olacaktır:

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

Herkes ben bu kullanarak Kriterleri API yazmak veya herhangi bir başka öneri/alternatif çözüm ben bir tasarıma yönelik olarak doğru yönde işaret edebilir HAVING sorunu çözmek için kullanabilir miyim?

budur Yukarıdaki örnekte

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"))); 

Teşekkür için sahip Kriterleri API kodu!

cevap

8

Hazırda/NHibernate FROM yan tümcesinde bir alt sorgu kullanmak için bir yol bilmiyorum ama WHERE yan tümcesinde kullanabilirsiniz. Herhangi bir Java/hazırda kod hataları için Özür dileriz, C#/NHibernate ile daha aşinayım.

 

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)); 

 

Bu kod benzer SQL neden olmalıdır:

 

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 
 

Bu yaklaşımın dezavantajı, bu miktarına bağlı olarak performansı üzerinde zararlı bir etkiye sahip olabilir, iki kez toplamlarının her ölçmesidir Eğer HAVING yan tümcesi desteklese bir HQL sorgusu kullanmak isteyeceğiniz bu durumda - veri karışan.

2

HHH-1700 HHH-1043 kopyası olarak işaretlendi ve bu nedenle sabit olmayacaktır. Sen HHH-1043 üzerine, benim çözüm ve geçici çözüm, hem de diğer halkları bulabilirsiniz.

+0

7 yıl önce ve hala hazırda bekletilmemiş, yama 4.3.6 ya da daha yeni bir sürüm için kullanmam gerekiyor, ancak kodun nasıl değiştirileceğine dair o kadar çok şey değişmişti. Bu düzeltme eki herkes tarafından güncellenir mi? –

İlgili konular