Ich habe dieses Problem in der Java-Version (Hibernate) behoben. Das Problem ist, dass die RowProjection Funktion ist etwas wie:
count(*)
Das ist eine Aggregatfunktion: Wenn Sie also eine ‚Gruppe von‘ Eigentum Ihr Ergebnis ist eine Liste der gruppierten Zeile und für jede Zeile erstellen müssen Sie die Gesamtzählung der Gruppe
Für mich mit Oracle-Datenbank, um es i funktioniert haben eine benutzerdefinierte Projektion erstellen, die anstelle der Funktion count erstellen (*), die Funktion ist
count(count(*))
und die Eigenschaft in der Gruppe Klausel wird nicht in die Anweisung select ... from geschrieben.Zu tun, dass es nicht so einfach, das Problem ist, dass Sie alle Stapel zu schaffen, haben das Recht, sql so, mit der Java-Version zu erstellen habe ich 2 Klasse subclasse: SimpleProjection ProjectionList
Danach meine Abfrage generiert als:
select count(*), col1, col2 from table1 group by col1, col2
werden
select count(count(*)) from table1 group by col1, col2
und das Ergebnis sind die Gesamtreihe von
gegebenen
select col1, col2 from table1 group by col1, col2
(verwendbar mit Paginierung System)
poste ich hier die Java-Version der Klassen, wenn nützlich sind für Sie da:
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;
}
}
Hope this Hilfe.
Ich möchte das gleiche tun ... aber vermeiden Sie die GetSql-Lösung. –
Ja, diese Lösung war schmerzhaft, benötigt, um die SQL aus den Kriterien zu bekommen, aber Sie können nicht die Parameter Typen oder Werte aus den Kriterien (auf einfache Weise), so dass wir eine andere Sammlung benötigt, um die Werte zu speichern, und sie müssen in der richtigen Reihenfolge usw. sein. –
Was hast du eigentlich in SQL geschrieben? Ich verstehe immer noch nicht, welches Ergebnis du brauchst. –