Fixed issues with average

This commit is contained in:
Maksim Kita 2020-12-16 23:10:40 +03:00
parent b82770c2ad
commit 5a096a75b8
2 changed files with 16 additions and 12 deletions

View File

@ -28,8 +28,8 @@ enum class AggregateOperation
* During array aggregation we derive result type from operation. * During array aggregation we derive result type from operation.
* For array min or array max we use array element as result type. * For array min or array max we use array element as result type.
* For array average we use Float64. * For array average we use Float64.
* For array sum for decimal numbers we use Decimal128, for floating point numbers Float64, for numeric unsigned Int64, * For array sum for for big integers, we use same type representation, decimal numbers we use Decimal128,
* and for numeric signed UInt64. * for floating point numbers Float64, for numeric unsigned Int64, and for numeric signed UInt64.
*/ */
template <typename ArrayElement, AggregateOperation operation> template <typename ArrayElement, AggregateOperation operation>
@ -127,10 +127,11 @@ struct ArrayAggregateImpl
using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>; using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>;
using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>; using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>;
/// For average on decimal array we return Float64 as result, but we want to keep presision /// For average of array we return Float64 as result, but we want to keep precision
/// so we convert to float64 as last step, but intermediate summ is represented as result of summ operation /// so we convert to Float64 as last step, but intermediate sum is represented as result of sum operation
static constexpr bool is_average_operation = aggregate_operation == AggregateOperation::average; static constexpr bool is_average_operation = aggregate_operation == AggregateOperation::average;
using SummAggregationType = ArrayAggregateResult<Element, AggregateOperation::sum>; using SummAggregationType = ArrayAggregateResult<Element, AggregateOperation::sum>;
using AverageAggregationType = ArrayAggregateResult<Element, AggregateOperation::average>;
using AggregationType = std::conditional_t<is_average_operation, SummAggregationType, Result>; using AggregationType = std::conditional_t<is_average_operation, SummAggregationType, Result>;
@ -247,14 +248,17 @@ struct ArrayAggregateImpl
if constexpr (aggregate_operation == AggregateOperation::average) if constexpr (aggregate_operation == AggregateOperation::average)
{ {
s = s / count; if constexpr (IsDecimalNumber<Element>)
}
if constexpr (IsDecimalNumber<Element> && aggregate_operation == AggregateOperation::average)
{ {
s = s / count;
res[i] = DecimalUtils::convertTo<Result>(s, data.getScale()); res[i] = DecimalUtils::convertTo<Result>(s, data.getScale());
} }
else else
{
res[i] = static_cast<AverageAggregationType>(s) / count;
}
}
else
{ {
res[i] = s; res[i] = s;
} }

View File

@ -1,7 +1,7 @@
Array min 1 Array min 1
Array max 6 Array max 6
Array sum 21 Array sum 21
Array avg 3 Array avg 3.5
Table array int min Table array int min
1 1
0 0
@ -15,7 +15,7 @@ Table array int sum
0 0
6 6
Table array int avg Table array int avg
3 3.5
0 0
2 2
Table array decimal min Table array decimal min