MDL-73706 reportbuilder: fix count for columns with multiple fields.

When using the "Count distinct" aggregation type on a column that
selects multiple fields, we should account for each of them in the
returned SQL.

Move helper method to facilitate this to the base aggregation class
so it can be re-used between all types.
This commit is contained in:
Paul Holden
2022-01-28 15:38:40 +00:00
parent e63604fb6d
commit eb2e261df4
4 changed files with 73 additions and 22 deletions
@@ -76,6 +76,38 @@ abstract class base {
return reset($sqlfields);
}
/**
* Helper method for concatenating given fields for a column, so they are suitable for aggregation
*
* @param string[] $sqlfields
* @param string $delimeter
* @return string
*/
final protected static function get_column_fields_concat(array $sqlfields, string $delimeter = ','): string {
global $DB;
$concatfields = [];
foreach ($sqlfields as $sqlfield) {
// We need to ensure all values are char (this ought to be done in the DML drivers, see MDL-72184).
switch ($DB->get_dbfamily()) {
case 'postgres' :
$sqlfield = "CAST({$sqlfield} AS VARCHAR)";
break;
case 'oracle' :
$sqlfield = "TO_CHAR({$sqlfield})";
break;
}
// Coalesce all the SQL fields, to remove all nulls.
$concatfields[] = "COALESCE({$sqlfield}, ' ')";
$concatfields[] = "'{$delimeter}'";
}
// Slice off the last delimeter.
return $DB->sql_concat(...array_slice($concatfields, 0, -1));
}
/**
* Return the aggregated field SQL
*