-
Notifications
You must be signed in to change notification settings - Fork 0
Aggregation
Aggregation is some operation that can be applied to a set of scalar values of the same type yielding a single scalar value result. For example, the sum operation adds up all of the scalar values in a column. Other common possibilities are min, max and avg (average). Aggregation is not a relational operation since it yields a scalar value rather than a relation.
So it is critical that any given aggregation operation be supported by the type it operates on. It makes no sense, for example, to take the average of a set of values of type Name since that type does not support addition. Many aggregation operations require at least one input value so, to avoid a run-time error, you must check for the empty set.
Scrall does not provide a predefined list of aggregation operations. These must be defined (or supplied automatically) as part of the type definition system since that is where supported operations are managed. Scrall merely provides a syntax for invoking an aggregation function on an attribute or table column.
Assuming an avg aggregation operation has been defined and is supported on the Altitude type, as one would expect since Altitude would be based on the Rational type, this works:
avg altitude = Aircraft(*).(Altitude).avg() // same result
When the dot notation is a suffix to a projection expression on one or more attributes it must designate an aggregation.
Since there is only one attribute, it can be shortened to get the same result since all attributes and all instances are implied:
avg altitude = Aircraft.Altitude.avg()
If there are zero instances of Aircraft, the assignment will fail with a run-time error since avg would need to divide by zero and min and max are not defined for empty sets. (You CAN define max so that it approximates negative infinity as the minimum system defined value, but it’s unclear that this would be useful). So, if you are not certain to obtain at least one instance with an aggregation operation that isn’t defined on the empty set, check first as shown:
Aircraft? avg altitude = Aircraft.Altitude.avg()
Above, we create a boolean condition as indicated by the ? symbol on the right of an implicit “select all” on Aircraft. If at least one is found, the average is computed. (Technically we need only do an Aircraft(1) select, but we’ll assume that the code generation is smart enough to figure this out since the selection is not assigned and merely tested).
To produce a table of heading and altitude averages, do this:
Aircraft? ha avgs #= Aircraft.(Heading, Altitude).avg()
To get the maximum altitude of all aircraft faster than a certain speed:
Aircraft? highfast alt = Aircraft( Airspeed > s ).Altitude.max()
Since there is a max symbol defined, you can do this which produces the same result:
Aircraft? highfast alt = Aircraft(1, Airspeed > s, +^Altitude).Altitude
You can specify an operation on the projected attribute as input into the aggregation like this:
totalCapacity = Duty Station.(Capacity * scale).sum()
Copyright 2020, 2021, 2022, 2023, 2025 © Leon Starr under MIT Open Source License
- Why they are problematic
- Instance attribute creation values
- Boolean values
- Special values
- Enumerated values
- Action block
- Statement
- Single line action
- Multiple dependent actions on a single line
- An action spread across multiple lines
- A conditional group of single line actions
- Comments
- Finding instances
- Attribute access
- Creation and deletion
- Subclass migration
- Creating a table from a class
- Creating a table with a definition
- Converting a table into a class
- Set operations on tables
- Set comparisons on tables
- Join
- Rename
- Extend
- Aggregation
- Rank
- Image
- Input values
- Signatures and name doubling
- Output values
- Execution order
- Sequential execution
- Conditional execution
- Signals
- Scrall has no for_each action
- Iteration