मैंने जावा संस्करण (हाइबरनेट) पर इस समस्या का समाधान किया है। समस्या RowProjection समारोह है कि है कुछ की तरह:
count(*)
एक समग्र समारोह है कि: इसलिए यदि आप संपत्ति 'द्वारा समूह' एक बनाने के अपने परिणाम वर्गीकृत किया पंक्ति की एक सूची है और प्रत्येक पंक्ति के लिए आपके पास समूह की कुल गिनती।
मेरे लिए, Oracle डाटाबेस के साथ, यह काम मैं कि, बजाय समारोह गिनती (*) बनाने के लिए एक कस्टम प्रक्षेपण बनाने है बनाने के लिए, समारोह
count(count(*))
और से समूह में संपत्ति है खंड से चयन ... में खंड नहीं लिखा गया है।यह इतना आसान नहीं है, समस्या आप जावा संस्करण के साथ तो सही एसक्यूएल बनाने के लिए, सभी ढेर प्रदान करने के लिए है कि यह है कि ऐसा करने के लिए मैं 2 वर्ग subclasse करना है: कि मेरी क्वेरी उत्पन्न होने के बाद SimpleProjection ProjectionList
के रूप में:
select count(*), col1, col2 from table1 group by col1, col2
select count(count(*)) from table1 group by col1, col2
हो जाते हैं और परिणाम कुल पंक्ति
द्वारा दिए गए हैं
(पृष्ठांकन प्रणाली के साथ प्रयोग करने योग्य)
मैं यहाँ पोस्ट वर्गों के जावा संस्करण, अगर आप के लिए उपयोगी होते हैं:
public class CustomProjectionList extends ProjectionList {
private static final long serialVersionUID = 5762155180392132152L;
@Override
public ProjectionList create() {
return new CustomProjectionList();
}
public static ProjectionList getNewCustomProjectionList() {
return new CustomProjectionList();
}
@Override
public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < getLength(); i++) {
Projection proj = getProjection(i);
String sqlString = proj.toSqlString(criteria, loc, criteriaQuery);
buf.append(sqlString);
loc += getColumnAliases(loc, criteria, criteriaQuery, proj).length;
if (i < (getLength() - 1) && sqlString != null && sqlString.length() > 0)
buf.append(", ");
}
return buf.toString();
}
private static String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery, Projection projection) {
return projection instanceof EnhancedProjection ?
((EnhancedProjection) projection).getColumnAliases(loc, criteria, criteriaQuery) :
projection.getColumnAliases(loc);
}
}
public class CustomPropertyProjection extends SimpleProjection {
private static final long serialVersionUID = -5206671448535977079L;
private String propertyName;
private boolean grouped;
@Override
public String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery) {
return new String[0];
}
@Override
public String[] getColumnAliases(int loc) {
return new String[0];
}
@Override
public int getColumnCount(Criteria criteria, CriteriaQuery criteriaQuery) {
return 0;
}
@Override
public String[] getAliases() {
return new String[0];
}
public CustomPropertyProjection(String prop, boolean grouped) {
this.propertyName = prop;
this.grouped = grouped;
}
protected CustomPropertyProjection(String prop) {
this(prop, false);
}
public String getPropertyName() {
return propertyName;
}
public String toString() {
return propertyName;
}
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
return new Type[0];
}
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery)
throws HibernateException {
return "";
}
public boolean isGrouped() {
return grouped;
}
public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
if (!grouped) {
return super.toGroupSqlString(criteria, criteriaQuery);
}
else {
return StringHelper.join(", ", criteriaQuery.getColumns(propertyName, criteria));
}
}
}
public class CustomRowCountProjection extends SimpleProjection {
/**
*
*/
private static final long serialVersionUID = -7886296860233977609L;
@SuppressWarnings("rawtypes")
private static List ARGS = java.util.Collections.singletonList("*");
public CustomRowCountProjection() {
super();
}
public String toString() {
return "count(count(*))";
}
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] {
getFunction(criteriaQuery).getReturnType(null, criteriaQuery.getFactory())
};
}
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
SQLFunction countSql = getFunction(criteriaQuery);
String sqlString = countSql.toString() + "(" + countSql.render(null, ARGS, criteriaQuery.getFactory()) + ") as y" + position + '_';
return sqlString;
}
protected SQLFunction getFunction(CriteriaQuery criteriaQuery) {
SQLFunction function = criteriaQuery.getFactory()
.getSqlFunctionRegistry()
.findSQLFunction("count");
if (function == null) {
throw new HibernateException("Unable to locate count function mapping");
}
return function;
}
}
आशा इस मदद करते हैं।
मैं वही काम करना चाहता हूं ... लेकिन GetSQL समाधान से बचें। –
हां, यह समाधान दर्दनाक था, मानदंडों से एसक्यूएल प्राप्त करने के लिए आवश्यक है लेकिन आप मानदंडों से पैरामीटर प्रकार या मान प्राप्त नहीं कर सकते हैं (एक आसान तरीके से) ताकि हमें मूल्यों को संग्रहीत करने के लिए एक और संग्रह की आवश्यकता हो, और उन्हें सही क्रम में होना आदि .. –
आपने वास्तव में एसक्यूएल में क्या रखा? मुझे अभी भी समझ में नहीं आता कि आपको क्या परिणाम चाहिए। –