in plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupBy.java [414:579]
void calcAggregate(Object[] row) throws HopValueException {
for (int i = 0; i < data.subjectnrs.length; i++) {
Aggregation aggregation = meta.getAggregations().get(i);
Object subj = row[data.subjectnrs[i]];
IValueMeta subjMeta = data.inputRowMeta.getValueMeta(data.subjectnrs[i]);
Object value = data.agg[i];
IValueMeta valueMeta = data.aggMeta.getValueMeta(i);
switch (aggregation.getType()) {
case Aggregation.TYPE_GROUP_SUM:
data.agg[i] = ValueDataUtil.sum(valueMeta, value, subjMeta, subj);
break;
case Aggregation.TYPE_GROUP_AVERAGE:
if (!subjMeta.isNull(subj)) {
data.agg[i] = ValueDataUtil.sum(valueMeta, value, subjMeta, subj);
data.counts[i]++;
}
break;
case Aggregation.TYPE_GROUP_MEDIAN,
Aggregation.TYPE_GROUP_PERCENTILE,
Aggregation.TYPE_GROUP_PERCENTILE_NEAREST_RANK:
if (!subjMeta.isNull(subj)) {
((List<Double>) data.agg[i]).add(subjMeta.getNumber(subj));
}
break;
case Aggregation.TYPE_GROUP_STANDARD_DEVIATION,
Aggregation.TYPE_GROUP_STANDARD_DEVIATION_SAMPLE:
if (!subjMeta.isNull(subj)) {
data.counts[i]++;
double n = data.counts[i];
double x = subjMeta.getNumber(subj);
// for standard deviation null is exact 0
double sum = value == null ? Double.valueOf(0) : (Double) value;
double mean = data.mean[i];
double delta = x - mean;
mean = mean + (delta / n);
sum = sum + delta * (x - mean);
data.mean[i] = mean;
data.agg[i] = sum;
}
break;
case Aggregation.TYPE_GROUP_COUNT_DISTINCT:
if (!subjMeta.isNull(subj)) {
if (data.distinctObjs == null) {
data.distinctObjs = new Set[meta.getAggregations().size()];
}
if (data.distinctObjs[i] == null) {
data.distinctObjs[i] = new TreeSet<>();
}
Object obj = subjMeta.convertToNormalStorageType(subj);
if (!data.distinctObjs[i].contains(obj)) {
data.distinctObjs[i].add(obj);
// null is exact 0, or we will not be able to ++.
value = value == null ? Long.valueOf(0) : value;
data.agg[i] = (Long) value + 1;
}
}
break;
case Aggregation.TYPE_GROUP_COUNT_ALL:
if (!subjMeta.isNull(subj)) {
data.counts[i]++;
}
break;
case Aggregation.TYPE_GROUP_COUNT_ANY:
data.counts[i]++;
break;
case Aggregation.TYPE_GROUP_MIN:
{
if (subj == null && !minNullIsValued) {
// do not compare null
break;
}
// set the initial value for further comparing
if (value == null && subj != null && !minNullIsValued) {
data.agg[i] = subj;
break;
}
if (subjMeta.isSortedDescending()) {
// Account for negation in ValueMeta.compare()
if (subjMeta.compare(value, valueMeta, subj) < 0) {
data.agg[i] = subj;
}
} else {
if (subjMeta.compare(subj, valueMeta, value) < 0) {
data.agg[i] = subj;
}
}
break;
}
case Aggregation.TYPE_GROUP_MAX:
if (subjMeta.isSortedDescending()) {
// Account for negation in ValueMeta.compare()
if (subjMeta.compare(value, valueMeta, subj) > 0) {
data.agg[i] = subj;
}
} else {
if (subjMeta.compare(subj, valueMeta, value) > 0) {
data.agg[i] = subj;
}
}
break;
case Aggregation.TYPE_GROUP_FIRST:
if (subj != null && value == null) {
data.agg[i] = subj;
}
break;
case Aggregation.TYPE_GROUP_LAST:
if (subj != null) {
data.agg[i] = subj;
}
break;
case Aggregation.TYPE_GROUP_FIRST_INCL_NULL:
// This is on purpose. The calculation of the
// first field is done when setting up a new group
// This is just the field of the first row
// if (linesWritten==0) value.setValue(subj)
break;
case Aggregation.TYPE_GROUP_LAST_INCL_NULL:
data.agg[i] = subj;
break;
case Aggregation.TYPE_GROUP_CONCAT_COMMA:
if (subj != null) {
StringBuilder sb = (StringBuilder) value;
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(subjMeta.getString(subj));
}
break;
case Aggregation.TYPE_GROUP_CONCAT_STRING_CRLF:
if (subj != null) {
StringBuilder sb = (StringBuilder) value;
if (sb.length() > 0) {
sb.append(Const.CR);
}
sb.append(subjMeta.getString(subj));
}
break;
case Aggregation.TYPE_GROUP_CONCAT_STRING:
if (subj != null) {
String separator = "";
if (!Utils.isEmpty(aggregation.getValue())) {
separator = resolve(aggregation.getValue());
}
StringBuilder sb = (StringBuilder) value;
if (sb.length() > 0) {
sb.append(separator);
}
sb.append(subjMeta.getString(subj));
}
break;
case Aggregation.TYPE_GROUP_CONCAT_DISTINCT:
if (subj != null) {
SortedSet<Object> set = (SortedSet<Object>) value;
set.add(subj);
}
default:
break;
}
}
}