How AGGREGATE Works

In the maintransform, LEFT refers to the next input record and RIGHT the result of the previous transform.

There are 4 interesting cases:

(a) If no records match (and the operation isn't grouped), the output is a single record with all the fields set to blank values.

(b) If a single record matches, the first record that matches calls the maintransform as you would expect.

(c) If multiple records match on a single node, subsequent records that match call the maintransform but any field expression in the maintransform that does not reference the RIGHT record is not processed. Therefore the value for that field is set by the first matching record matched instead of the last.

(d) If multiple records match on multiple nodes, then step (c) performs on each node, and then the summary records are merged. This requires a mergetransform that takes two records of type RIGHT. Whenever possible the code generator tries to deduce the mergetransform from the maintransform. If it can't, then the user will need to specify one.

inRecord := RECORD 
  UNSIGNED box; 
  STRING text{MAXLENGTH(10)}; 
END; 
inTable := DATASET([{1,'Fred'},{1,'Freddy'},
                    {2,'Freddi'},{3,'Fredrik'},{1,'FredJon'}], inRecord);
      
//Example 1: Produce a list of box contents by concatenating a string:
      
outRecord1 := RECORD 
  UNSIGNED box; 
  STRING contents{MAXLENGTH(200)}; 
END; 
outRecord1 t1(inRecord l, outRecord1 r) := TRANSFORM 
  SELF.box := l.box; 
  SELF.contents := r.contents + IF(r.contents <> '', ',', '') + l.text; 
END; 
      
outRecord1 t2(outRecord1 r1, outRecord1 r2) := TRANSFORM 
  SELF.box := r1.box; 
  SELF.contents := r1.contents + ',' + r2.contents; 
END; 
OUTPUT(AGGREGATE(inTable, outRecord1, t1(LEFT, RIGHT), t2(RIGHT1, RIGHT2), LEFT.box));
      
//This example could eliminate the merge transform if the SELF.contents expression in
//the t1 TRANSFORM were simpler, like this:
//     SELF.contents := r.contents + ',' + l.text;
//which would make the AGGREGATE function like this:
//   OUTPUT(AGGREGATE(inTable, outRecord1, t1(LEFT, RIGHT), LEFT.box));

      
//Example 2: A PIGMIX style grouping operation:
outRecord2 := RECORD 
  UNSIGNED box; 
  DATASET(inRecord) items; 
END; 
outRecord2 t3(inRecord l, outRecord2 r) := TRANSFORM 
  SELF.box := l.box; 
  SELF.items:= r.items + l; 
END; 
OUTPUT(AGGREGATE(inTable, outRecord2, t3(LEFT, RIGHT), LEFT.box));

See Also: TRANSFORM Structure, RECORD Structure, ROLLUP, TABLE