Skip to content

Helpers: Sum, SumIf and friends ​

The helpers turn a list of values into one value. They behave like their Excel namesakes, and they skip empty values instead of failing on them.

They're available in every aggregated field and every dynamic column. In a dynamic column they're most useful when the data source has a Reference only child, because that's when a dynamic column has lists to work with.

Reference menu of an aggregated field, listing the helpers

Simple helpers ​

HelperReturnsIgnoresEmpty list gives
Sum({[Amount]})totalempty values, text, NaN (even "12" as text)0
Average({[Amount]})meansame as Sumempty
Median({[Amount]})middle valuesame as Sumempty
Min({[Amount]}) / Max({[Amount]})smallest / largest number, or earliest / latest date for date fieldsempty valuesempty
Count({[Title]})number of non-empty valuesnull, ''0
CountDistinct({[Owner]})number of different non-empty valuesnull, ''0
First({[Title]}) / Last({[Title]})first / last non-empty valuenull, ''empty

Numbers stored as text are skipped

Sum adds up real numbers only. If a column holds numbers as text, convert them first: Sum({[Amount]}.map(Number)).

Conditional helpers ​

js
SumIf(values, criteriaValues, criterion)
AverageIf(values, criteriaValues, criterion)
CountIf(criteriaValues, criterion)

They go through the rows side by side: the 1st value is kept if the 1st criteria value matches, the 2nd if the 2nd matches, and so on.

criterion is either:

  • a value: an exact match ('Open', false, 3), or
  • a test written as a small function: (status) => status !== 'Done'.

From the demo's Project costs data source:

js
SumIf({[Expenses_Amount]}, {[Expenses_Approved]}, false)            // Pending approval = 6850
SumIf({[Expenses_Amount]}, {[Expenses_Category]}, 'Hardware')       // Hardware spend = 16800
SumIf({[Tasks_Hours]}, {[Tasks_Status]}, (status) => status !== 'Done') // Open task hours = 85
CountIf({[Budget status]}, 'Over budget')                           // Projects over budget = 1

Open task hours: SumIf with a test function over a reference child

Use lists from the same data source

SumIf({[Tasks_Hours]}, {[Status]}, ...) mixes task hours with project statuses. The two lists have different lengths and unrelated orders, so the result is meaningless. Nothing warns you about this, so take care: both lists should come from the same source (Tasks_... with Tasks_...).

Snippets ​

The Snippets menu of an aggregated field:

Snippets menu of an aggregated field

SnippetFormulaNotes
SumSum({[Value]})Total of a numeric field
AverageAverage({[Value]})Mean, ignoring empty values
Count whereCountIf({[Status]}, 'Open')Rows matching a value. For a test, use CountIf({[Status]}, (s) => s !== 'Done')
Distinct countCountDistinct({[Value]})Unique values, e.g. number of customers
Latest dateMax({[Date]})Set the type to Date and Time. Min gives the earliest
Ratio of two aggregated fields{[Won]} / {[Total]}Both tokens are aggregated fields, so this is plain arithmetic

Replace each placeholder (Value, Status, Date, Won, Total) with a real field after inserting.

The editor helps you ​

  • Σ next to a field inserts a helper that suits the field's type.
  • Right-click a field token in the formula for Aggregate: ... actions that wrap it in a helper.
  • Typing a helper name shows its parameters and description.