#1404 - Query.findCount() with query.setDistinct(true) ... doesn't give count distinct SQL query

This commit is contained in:
rob bygrave
2018-06-07 00:32:39 +12:00
parent eca6383dba
commit eba1003c19
9 changed files with 130 additions and 25 deletions
@@ -241,10 +241,14 @@ class CQueryBuilder {
ManyWhereJoins manyWhereJoins = query.getManyWhereJoins();
if (manyWhereJoins.isFormulaWithJoin()) {
query.select(manyWhereJoins.getFormulaProperties());
} else {
query.setSelectId();
boolean countDistinct = query.isDistinct();
if (!countDistinct) {
// minimise select clause for standard count
if (manyWhereJoins.isFormulaWithJoin()) {
query.select(manyWhereJoins.getFormulaProperties());
} else {
query.setSelectId();
}
}
CQueryPredicates predicates = new CQueryPredicates(binder, request);
@@ -263,23 +267,35 @@ class CQueryBuilder {
}
boolean hasMany = sqlTree.hasMany();
String sqlSelect = "select count(*)";
if (hasMany) {
// need to count distinct id's ...
query.setSqlDistinct(true);
sqlSelect = null;
String sqlSelect = null;
if (countDistinct) {
if (sqlTree.isSingleProperty()) {
request.setInlineCountDistinct();
}
} else {
if (hasMany) {
// need to count distinct id's ...
query.setSqlDistinct(true);
} else {
sqlSelect = "select count(*)";
}
}
SqlLimitResponse s = buildSql(sqlSelect, request, predicates, sqlTree);
String sql = s.getSql();
if (hasMany || query.isRawSql()) {
int pos = sql.lastIndexOf(" order by "); // remove order by - mssql does not accept order by in subqueries
if (pos != -1) {
sql = sql.substring(0, pos);
}
sql = "select count(*) from ( " + sql + ")";
if (selectCountWithAlias) {
sql += " as c";
if (!request.isInlineCountDistinct()) {
if (countDistinct) {
sql = wrapSelectCount(sql);
} else if (hasMany || query.isRawSql()) {
// remove order by - mssql does not accept order by in subqueries
int pos = sql.lastIndexOf(" order by ");
if (pos != -1) {
sql = sql.substring(0, pos);
}
sql = wrapSelectCount(sql);
}
}
@@ -290,6 +306,14 @@ class CQueryBuilder {
return new CQueryRowCount(queryPlan, request, predicates);
}
private String wrapSelectCount(String sql) {
sql = "select count(*) from ( " + sql + ")";
if (selectCountWithAlias) {
sql += " as c";
}
return sql;
}
/**
* Return the SQL Select statement as a String. Converts logical property
* names to physical deployment column names.
@@ -536,6 +560,9 @@ class CQueryBuilder {
if (!useSqlLimiter) {
sb.append("select ");
if (query.isDistinctQuery()) {
if (request.isInlineCountDistinct()) {
sb.append("count(");
}
sb.append("distinct ");
String distinctOn = select.getDistinctOn();
if (distinctOn != null) {
@@ -551,6 +578,9 @@ class CQueryBuilder {
} else {
sb.append(select.getSelectSql());
}
if (request.isInlineCountDistinct()) {
sb.append(")");
}
if (query.isDistinctQuery() && dbOrderBy != null && !query.isSingleAttribute()) {
// add the orderBy columns to the select clause (due to distinct)
sb.append(", ").append(DbOrderByTrim.trim(dbOrderBy));