2010-12-29 11 views
6

में पहले aliased क्षेत्र का जिक्र करते हुए इस क्वेरी में:एक मापदंड क्वेरी

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Tuple> q = cb.createTupleQuery(); 

// FROM GamePlayedEvent gpe 
Root<GamePlayedEvent> gpe = q.from(GamePlayedEvent.class); 
// SELECT gameId, COUNT(*) AS count, AVG(duration) 
// AS avDur, AVG(rewardCurrency) AS avCur, AVG(rewardXP) avXp 
q.select(cb.tuple(
    gpe.<String>get("gameId"), 
    cb.count(gpe).alias("count"), 
    cb.avg(gpe.<Double>get("duration")).alias("avDur"), 
    cb.avg(gpe.<Integer>get("rewardCurrency")).alias("avCur"), 
    cb.avg(gpe.<Integer>get("rewardXp")).alias("avXp") 
)); 
// WHERE loginTime BETWEEN ... 
q.where(cb.between(gpe.<Date>get("time"), fromTime, toTime)); 
// GROUP BY gameId 
q.groupBy(gpe.<String>get("gameId")); 
// ORDER BY count DESC 
q.orderBy(cb.desc(???)); 

मैं ORDER BY count DESC कैसे जोड़ सकते हैं, "गिनती" SELECT खंड में परिभाषित की चर्चा करते हुए?

उत्तर

7

क्या होगा यदि आपने अभी गिनती अभिव्यक्ति पर कब्जा कर लिया है, और इसे सीधे इस्तेमाल किया है?

Expression event_count = cb.count(gpe); 

q.select(cb.tuple( 
    gpe.<String>get("gameId"), 
    event_count, 
    ... 
)); 

q.orderBy(cb.desc(event_count)); 
0

क्या आपने उपनाम के साथ प्रक्षेपण स्थापित करने का प्रयास किया है?

criteria.setProjection(Projections.projectionList() 
    .add(Projections.count("item.id"), "countItems")); 
criteria.addOrder(Order.desc("countItems")); 
+0

यह हाइबरनेट मानदंड API है। यह प्रश्न जेपीए 2 मानदंड एपीआई (और यह हाइबरनेट कार्यान्वयन) के बारे में है। उलझन में पर्याप्त, वे एक ही बात नहीं हैं। –

1

हालांकि प्रो जेपीए 2 पुस्तक का वर्णन है कि उर्फ ​​विधि एक एसक्यूएल क्वेरी उर्फ ​​(पेज 251 पर) उत्पन्न करने के लिए इस्तेमाल किया जा सकता मैं यह न तो EclipseLink के साथ काम या हाइबरनेट बनाने के साथ कोई सफलता मिली है। अपने प्रश्न के लिए मैं कहूँगा कि अपने orderBy लाइन पढ़ना चाहिए:

q.orderBy(cb.desc(cb.count(gpe)); 

अगर यह विभिन्न विक्रेताओं द्वारा समर्थित किया गया।

जहां तक ​​मेरा शोध जाता है, यह उपनाम है कि उपनाम विधि का उपयोग केवल चयन में उपयोग किए गए ट्यूबल में तत्वों का नामकरण करने के लिए किया जाता है (इसलिए केवल प्रक्षेपण के लिए)।

हालांकि मेरे पास एक प्रश्न है। आप इस क्वेरी के लिए जेपीए मानदंड API का उपयोग क्यों करना चाहेंगे। यह (क्वेरी) प्रकृति में स्थैतिक होने के लिए सीम है, इसलिए जेपीक्यूएल का उपयोग क्यों न करें जहां आप सीधे अपने प्रश्न उपनाम को परिभाषित कर सकते हैं।

0

मैं आज एक ही समस्या भर में आया था, लेकिन सुझाव दिया समाधान में से कोई भी मेरे लिए काम किया है क्योंकि मैं न केवल order by खंड में, लेकिन यह भी group by खंड में अभिव्यक्ति पुन: उपयोग करने की जरूरत है। डेटाबेस स्तर पर एक दृश्य बनाने के लिए एक स्पष्ट समाधान होगा, लेकिन यह थोड़ा बेकार है, एक अनावश्यक सबक्वायरी बनाता है और यहां तक ​​कि यदि संभव नहीं है तो डीबी उपयोगकर्ता को पर्याप्त विशेषाधिकार नहीं दिए जाते हैं। एक बेहतर विकल्प है, जो कार्यान्वयन के लिए मैं समाप्त हो गया इस

q.select(cb.tuple( 
    gpe.<String>get("gameId"), 
    cb.count(gpe), 
    ... 
)).groupBy(cb.literal(2)).orderBy(cb.literal(2)); 

इस दृष्टिकोण के पहले नकारात्मक पक्ष यह है कि कोड errorprone है की तरह कुछ लिखने के लिए है। दूसरी कमी यह है कि जेनरेट की गई SQL क्वेरी में क्रमिक स्थिति नोटेशन होता है, जो कुछ डेटाबेस (जैसे postgresql या mariadb) पर काम करता है लेकिन दूसरों पर काम नहीं करता (जैसे SQL सर्वर)। हालांकि, मेरे मामले में, मैंने यह सबसे अच्छा विकल्प पाया।

एक प्रदाता और postgresql 9.6 के रूप में hibernate 5.2.3 के साथ जेपीए 2.1 पर परीक्षण किया।

संबंधित मुद्दे