void calcAggregate()

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;
      }
    }
  }