Skip to main content
Use aggregate functions in custom metrics. Custom metrics can also include the use of row-level functions, conditional CASE expressions, statistical functions, an expansive list of arithmetic functions, as well as FIRST and LAST values. In addition, they can be filtered (using date and time filter functions and SQL-like expressions). Data can be aggregated using column, table, or window aggregation functions. Each is explained in the links below. Aggregation functionality is explained in the links below.

Column Aggregation Functions

Column aggregation functions aggregate data using all the data displayed on a visual. They group results in the same way that the visual itself groups its data. For example, if your visual shows data grouped by gender (male and female), then column aggregation functions return two results, one for males and one for females. Only data included in the visual by any filters that have been applied are included in the results. The following table describes the supported column aggregation functions.
FunctionParameter TypeDescription
AVG(<field>)numericReturns the average of a column (field), grouped in the same manner as the visual data.
COUNT(<field>)anyReturns the numeric count of values in a column (field), grouped in the same manner as the visual data.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data.
Use the wildcard character (*) for <field> to include null values for the field in the count.
COUNTD(<field>)anyReturns the numeric count of unique values in a column (field), grouped in the same manner as the visual data.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data.
Use the wildcard character (*) for <field> to include null values for the field in the count.
MAX(<field>)numericReturns the maximum value of a column (field), grouped in the same manner as the visual data.
MIN(<field>)numericReturns the minimum value of a column (field), grouped in the same manner as the visual data.
SUM(<field>)numericReturns the sum of a column (field), grouped in the same manner as the visual data.
FIRST_VALUE(<field>)anyReturns the first value of a given expression in the group, as when the expression is sorted in the ascending order.
LAST_VALUE(<field>)anyReturns the last value of a given expression in the group, as when the expression is sorted in the ascending order.
STDDEV_POP(<field>)numericComputes the population standard deviation and returns the square root of the population variance.
STDDEV_SAMP(<field>)numericComputes the cumulative sample standard deviation and returns the square root of the sample variance.
VAR_POP(<field>)numericReturns the population standard variance of a given expression.
VAR_SAMP(<field>)numericReturns the sample variance of a given expression.
MEDIAN(<field>)numericComputes the median value across the group.

Example

Suppose you have the following fields and data in a data source: To use this data set to create a custom metric called Leftover (a group’s leftover money), use the following formula.
If you used the Leftover custom metric in a visual grouping by gender using the data above, you would get the results shown below. Males have $7, derived from (10+8+2) - (2+3+8). Females have -$2 left over, derived from (5+4) - (5+6). If you used the same custom metric in a visual grouping by city, you would see Rockville having $13, from (10+8+5) - (2+3+5), and Reston having -$8, from (4+2) - (6+8).

Date and Time Filter Aggregation Functions

To filter a custom metric using dates or times, you must already have a time attribute configured in your data source. The following date and time functions can only be used after WHERE in your custom metric. Date field options use common time formats such as YTD, MMDDYYYY, and YoY. The following date and time filter aggregation functions are supported.
Supported Date and Time Functions
FunctionDescription
DATE()Deprecated. Use NOW() instead.
DateADD('<time_period>',<interval>,'<date>')Deprecated. Use TIME_ADD instead.
For example, consider this DateADD specification:

Use this TIME_ADD specification instead:

In a second example, consider this DateADD specification:

Use this TIME_ADD specification instead:
DateSUB('<time_period>',<interval>,'<date>')Deprecated. Use TIME_ADD instead, specifying a negative number for interval.
For example, consider this DateADD specification:

Use this TIME_ADD specification instead:

TIME_ADD supports negative interval numbers for subtraction.
NOW()Obtains the current date and time for the derived field. NOW() functionality is available when you use a supported connector.
Set the calculations.rle.now.function property in the query-engine.properties file to true and restart the query engine microservice.
See Query Engine Properties.
PreviousPeriod(<offset>,<numPeriods>)This function is supported only within a TRANSFORM clause used for filtering the custom metric.
The period returned is of the same length as the currently represented period, but not immediately prior to it. Instead, it counts back in <numPeriods> periods of time, measured in units named by <offset>.
The following time <offset> values are supported: YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, MILLISECOND.
See PreviousPeriod Function.
TIME()Deprecated. Use NOW() instead.
TIME_ADD('<time-period>',<interval>, <date-time-field>)Adds an interval value to the <timepart> of the date-time field:
In the following example, 7 is added to the hour in the field called date_time_field:

Date Filter Functions

Specific parameters are needed for the DateADD and DateSub functions. The following table describes them.
ParameterValue
time_periodSupported time periods (with corresponding interval range): YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, MILLISECOND
intervalWhole number integer. Negative numbers are supported for subtraction.
date
  • Current day operator: date()

  • Standard date and time formats supported include:

  • yyyy-MM-dd HH:mm:ss
  • MM/dd/yy hh:mm aa
  • yyyy

For all supported formats, see Convert Attributes to Time Fields in Data Source Field Specifications.

PreviousPeriod Function

The PreviousPeriod function is used for comparing data values between different time periods. This function can be used when you need to compare one time period to another of equivalent size for variance custom metrics. For example, comparing results from the current month to the previous month or the current week to the same week one year ago.
Note that this function only works when the date field used in the formula is selected on the time bar.
To use this function, the TRANSFORM SQL-like expression must be used in the custom metric to convert the date range for a specified time attribute. For example:
If the saledate time period is March 2015, the custom metric returns SUM(Sales) where the saledate is February 2015.
If the data is grouped by the same field for which a PreviousPeriod transformation is performed and it is grouped by days but transformed by units of months, quarters, or years, null values are returned when the previous period does not have matching days for the current period. For example, if the current period is the month of March and PreviousPeriod('month',1) is used for the transformation, null values are produced for February 29-31, 2015 because those days are not valid days (although they are valid days for March 2015). Self-Service Analytics attempts to preserve the day-of-month correspondence between the two periods.
Specific parameters must be specified in PreviousPeriod functions. The following table describes them.

Table Aggregation Functions

Table aggregation functions are broader in scope than column aggregation functions. Table aggregation functions use all data from a field and produce a single, ungrouped value. You typically do not use the result directly in a visual, since it is ungrouped. For example, if you have sales records grouped by gender, a TableSUM custom metric returns the total sales of all records as one value, regardless of the group in consideration. The TableSUM result would include both the male and female data values. Consequently, males and females would appear to have the same sales if the TableSUM result was included in the visual. Table aggregation functions are typically used to calculate percentages of a whole or average values. The following table describes the supported table aggregation functions.
FunctionTypeDescription
TableAVG(<field>)numericReturns the average of a column (field), regardless of how the visual is grouped.
TableCOUNT(<field>)anyReturns the numeric count of values in a column (field), regardless of how the visual is grouped.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data. Use the wildcard character (*) for <field> to include null values for the field in the count.
TableCOUNTD(<field>)anyReturns the numeric count of unique values in a column (field), regardless of how the visual is grouped.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data. Use the wildcard character (*) for <field> to include null values for the field in the count.
TableMAX(<field>)numericReturns the maximum value of a column (field), regardless of how the visual is grouped.
TableMIN(<field>)numericTableMIN returns the minimum value of a column (field), regardless of how the visual is grouped.
TableSUM(<field>)numericTableSUM returns the sum of a column (field), regardless of how the visual is grouped.

Example

Suppose you have the following fields and data: Using this data, you can create a custom metric containing individual earnings as a percentage of total earnings with the following formula:
in which:
  • SUM(earned) calculates the sum earnings for each individual.
  • TableSUM(earned) calculates the total earnings of all records in the data.
  • The quotient of SUM(earned) / TableSUM(earned) is multiplied by 100 to convert the result into a percentage.
Shown on a table using the example data above, the results would look like this:

Window Aggregation Functions

Window aggregation functions are a middle case between column and table aggregation functions. They provide a snapshot or window into a subset of data, depending on the groupings used by the visual. Each window function such as WindowSUM or WindowAVG requires a numeric field to aggregate followed by a list of one or more attributes. The function aggregates the data and groups the results based on these attributes if the attributes are present in the visual. Attributes absent from the visual are ignored from the aggregation. Derived fields can be used in window aggregation functions. For example, an aggregation WindowAVG( profits, gender, city ) returns the average profits in the data, grouped by gender and city if gender and city are represented in the visual. If gender happens to be absent from the visual, then it is dropped from the aggregation. Effectively, the average profits would then be grouped only by city. The following table describes the supported window aggregation functions.
FunctionTypeDescription
WindowAVG(<field>,<attr1>[,<attr2>]...)numericReturns the average of a column (field), grouped by the specified attributes.
WindowCOUNT(<field>,<attr1>[,<attr2>]... )anyReturns the numeric count of values in a column (field), grouped by the specified attributes.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data.
Use the wildcard character (*) for <field> to include null values for the field in the count.
WindowCOUNTD(<field>,<attr1>[,<attr2>]...)anyReturns the numeric count of unique values in a column (field), grouped by the specified attributes.
This aggregate function normally ignores null values for the specified field. Consequently, the result of this aggregate function may not be the same as the actual number of records in the data.
Use the wildcard character (*) for <field> to include null values for the field in the count.
WindowMAX(<field>,<attr1>[,<attr2>]...)numericReturns the maximum value of a column (field), grouped by the specified attributes.
WindowMIN(<field>,<attr1>[,<attr2>]...)numericReturns the minimum value of a column (field), grouped by the specified attributes.
WindowSUM(<field>,<attr1>[,<attr2>]...)numericReturns the sum of a column (field), grouped by the specified attributes.

Example

Suppose you have the following fields and data: To create a custom metric containing a group’s contribution to just gender, rather than to the whole, use the following formula.
Using this custom metric in a pivot table with the example data set shown above produces results similar to the ones shown below.
CityGenderVolume% of Each Gender’s Earnings
RestonF144.44
M110
RockvilleF155.56
M290
Total5100
In this pivot table, each city’s total earnings (SUM(earned)) is shown as a percentage of each gender’s total earnings. If gender had been absent from the visual, the cities’ total earnings would have been shown as totals of the whole, rather than of each gender.

Arithmetic Functions

Custom metrics support the following arithmetic functions in your aggregate functions. The following table describes the supported arithmetic functions.

Conditional CASE Expressions

You can include the use of CASE expressions (singular or nested) in your custom metrics, much as you would row-level case and SQL case expressions. These capabilities include: Conditions in when :
  • Condition must be an aggregate-level expression.
  • Can compare both metrics and groups. Group values, or any other non-numeric values can be used through FIRST_VALUE / LAST_VALUE functions.
  • Use existing metrics from the request or add new metrics.
  • Row-level expressions can be used inside aggregation functions.
  • Use AND / OR operators to build complex conditions.
  • where and transform clauses can be used in conditions to modify aggregate expressions.
To return results in thenthat include custom metric expressions, including calculated sub-queries.
  • Must be an aggregate-level expression.
  • All result values must be of the same type.
  • Can be a numeric or non-numeric value.
  • where and transform clauses can be used in conditions to modify aggregate expressions.
Additionally, you can nest case functions if needed, both for conditions and results. If you use case expressions as part of an arithmetic expression, it must be enclosed in parentheses.
Only one result branch is returned from the expression, but all branches will be evaluated simultaneously, regardless of which condition is met first.

Supported Statistical Functions

Supported Row-Level Functions

Use row-level functions in the row-level expressions you use to create the following calculation types: The row-level functions described in this section are fully supported by all three types. For information about the aggregate functions and SQL-like expressions you can use in custom metrics, see Supported Aggregation Functions and Supported SQL-Like Expressions. Row-level functions are divided into the following categories:

Arithmetic Functions

Conditional Functions

OperatorDescription
CASEUse the CASE function is the same manner as standard SQL CASE functions. CASE can be used to list a series of conditions and return an appropriate value for the first condition that is met.
COALESCEUse the COALESCE function in the same manner as standard SQL COALESCE functions. COALESCE can be used to return the first non-null value in a list of values.
The COALESCE function also supports aggregate metrics with complex calculations using arithmetic functions (for example COALESCE(max(sales) * 1.3, 0)), so a default value can be used if null values are returned.

Logical Functions

Numerical Functions

FunctionDescriptionExample
CEILReturns the smallest integer value that is not less than the passed ValueCEIL(value : Numeric) : Numeric
CEIL(Field_A)
FLOORReturns the largest integer value that is not greater than the passed valueFLOOR(value : Numeric) : Numeric
FLOOR(Field_A)
NUM_TO_TEXTConverts the numeric expression to textNUM_TO_TEXT(value : Numeric)
NUM_TO_TEXT(Field_A)
ROUNDRounds a numeric value to the number of decimals specifiedROUND(Field_A, 0)
UNIX_TIME_TO_TIMEConverts the numeric expression to timeUNIX_TIME_TO_TIME(Field_Milliseconds /1000)

Relational Functions

You can also combine less than (<) and greater than (>) functions using logical AND processing in the same statement. For example, the following are valid statements:
In each of these examples, the individual relational functions must all be true for the full statement to be true. In the second example, the sale date must be greater than October 28, 2020 and less than October 30, 2020 and the sale must take place in the state of California.

Text Functions

FunctionDescriptionExample
CONCATReturns a text that is the result of concatenating two or more text values.CONCAT(Field_FirstName, ' ,', Field_LastName)
LENGTHReturns the number of characters of the specified string.LENGTH(SUBSTRING('$12456.00', 2, 10))
LOCATEFinds the first occurrence of substring in a string, starting at position.LOCATE('Mr.', CONCAT(Field_FirstName, ' ,', Field_LastName), 0)
LOWERReturns the argument in lowercase.LOWER(SUBSTRING(Field_A, 0, 3 ))
LPADReturns the text argument, left-padded with the text specified by padString to a length of Length characters.LPAD(SUBSTRING(Field_A, 0, 15), 3, 'abc')
LTRIMReturns a text value after removing leading blanks.LTRIM(SUBSTRING(Field_A, 0, 5))
RPADReturns the Text argument, right-padded with the text specified by padString to a length of Length characters.RPAD(SUBSTRING(Field_A, 0, 15), 3, 'abc')
RTRIMReturns a text value after removing trailing blanks.RTRIM(SUBSTRING(Field_A, 0, 5))
SUBSTRINGReturns the substring of String value which begins at position defined by Start and is Length characters long.SUBSTRING(Field_A, 4, 3)
TEXT_TO_NUMConverts the text string to numeric.TEXT_TO_NUM(LTRIM(Field_A))
TEXT_TO_TIMEConverts the text expression to time according to the specified format.
This function requires input in the form of an attribute or string field containing data that could be parsed as a time field and the format for the time field.
Valid formats must be enclosed in single quotation marks and can only use the following syntax elements: YYYY (for years), MM (for months), DD (for days), HH24 (for hours), MI (for minutes), SS (for seconds), and MS (for milliseconds).
Separators in the syntax that are allowed are - (dashes), : (colons), . (periods), / (backslashes), and spaces.
TEXT_TO_TIME(Field_A,'YYYY-MM-DD HH24:MI:SS')
UPPERReturns the argument in uppercase.UPPER(SUBSTRING(Field_A, 0, 3))

Time Functions

The following time functions are supported. Valid values for <timepart> vary, based on the Self-Service Analytics connector selected, but can include YEAR, QUARTER, MONTH, WEEK, WEEK_OF_YEAR, WEEK_OF_MONTH, DAY, DAY_OF_YEAR, DAY_OF_MONTH, DAY_OF_WEEK, HOUR, MINUTE, SECOND, or MILLISECOND. Review the documentation for the Self-Service Analytics connector for any deviations from this list. Note that the WEEK_OF_YEAR function calculates the week from January 1, not from the week containing January 1.
FunctionDescription
EXTRACTExtracts the <timepart> of the <datetime> field:
NOWObtains the current date and time for the derived field. NOW() functionality is available when you use a supported connector. Set the calculations.rle.now.function property in the query-engine.properties file to true and restart the query engine microservice. See Query Engine Properties.
TIME_ADDAdds an interval value to the <timepart> of the <datetime> field:

In the following example, 7 is added to the hour in the field called date_time_field:
TIME_DIFFReturns the time difference between two time fields in the unit you request:

In the following example, the difference between the values of the ENDDATE and STARTDATE fields is returned in days:
TIME_TO_UNIX_TIMEReturns the value of a <datetime> field as a Unix time stamp:
TRUNCATE_TIMERounds (Truncates) the <datetime> field value down to the granularity specified by <timepart>:

Metric Aggregation Functions

provides a set of metric functions that are used to group (aggregate) data. The following aggregation methods can be selected for metrics in your visuals. See also Metrics.
Aggregation FunctionWhat Is Returned
AVGThe average of the data values for the field. This function is available only for numeric fields.
DISTINCT COUNTThe total number of unique values for the field. This function is available only for attribute and numeric fields.
COUNTThe total number of values for the field. This function is available only for attribute and numeric fields.
MINThe lowest value in all the data values for the field. This function is available only for numeric fields.
MAXThe highest value in all the data values for the field. This function is available only for numeric fields.
SUMThe total of all the data values for the field. This function is available only for numeric fields.
LAST VALUEThe last value in all the data values for the field, sorted by the time attribute selected for the time bar. If the latest date and time for the time attribute is exactly the same in multiple records, the last value for the field is the maximum value of the field in the records with the latest date and time. See LAST VALUE Examples. This function is available only for numeric fields.
NO AGGREGATIONNo Aggregation is available if you group and sort by the same field. When you use No Aggregation, you can select the sort Order of as Alphabetical (A-Z) or Reverse Alphabetical (Z-A).
LISTAGGUse to transform row-level data into a string of consolidated data, comma-separated data, or other custom-delimited string. For example, use Listagg(fieldname, 'delimiter') to concatenate the fields values, separated by the defined delimiter.
Pushdown is supported for multiple connectors:
BigQuery, Impala, MySQL, MemSQL, Oracle, PostgreSQL, Redshift, Snowflake, and SparkSQL.
Suppose you have the following raw data: When this data is aggregated by gender, only two records (one for males and one for females) are returned and the aggregation must somehow determine what value to return for the age of the different genders. To do this, the aggregation requires input (using a metric function) about how the age should be returned. For example, if you elected to aggregate the data by gender and return the average age using the AVG metric function, the resulting data would be: If you elected to aggregate the data by gender and return the minimum age using the MIN metric function, the resulting data would be:

LAST VALUE Examples

The LAST VALUE examples in this section use the following data:

Examples: Grouping By One Field

Suppose you aggregate this data by Gender and request that the last value for Price be returned based on the Sale_Date. The results would be: Suppose you aggregate this data by Country and request that the last value for Price be returned based on the Sale_Date. The results would be:

Example: Grouping By Two Fields

Suppose you aggregate this data by Gender and then by Country and request that the last value for Price be returned based on the Sale_Date. The results would be:

Example: Grouping By Two LAST VALUE Metrics

Suppose you aggregate this data by Gender and request that the last value for Price and the last value for Items be returned based on the Sale_Date. The results would be:

Supported SQL-Like Expressions

Self-Service Analytics’s custom metrics support the following SQL-like expressions:
ExpressionDescription
WHEREUse WHERE to filter by a condition. Data will only be included in the custom metric if the condition that follows is true. For example:

Row-level functions and expressions can be used in WHERE clauses in custom metrics. In a custom metric, WHERE clauses allow you to specify a formula without first creating a derived field. The WHERE clause must be in the leftmost part of the custom metric expression, but it can be expressed with a row-level function or any of the aggregate functions available for custom metrics. In the following example, the total planned sales is calculated for men.
ANDUse AND to form a conjunctive condition. Data is only included in the custom metric if it meets both of the conditions connected by AND. The following example calculates the sum of deicing only if the broadphaseofflight includes LANDING and the airportcode is YYZ.
ORUse OR to for a disjunctive condition. Data is included in the custom metric if it meets either of the conditions connected by OR. The following example calculates the sum of deicing if the broadphaseofflight includes LANDING or the airportcode is YYZ.
BETWEEN…ANDUse BETWEEN to filter using a range of values. The following example counts the number of distinct records for weatherdelay that have cancelledflight counts between 2 and 10.
INUse IN to filter using a set of values. Data is included in the custom metric only if a data field matches one of the listed values. The following example calculates the sum of weatherdelay only for records in which the airportcode field is LAX, ORD, or IAD.
NOT INUse NOT IN to filter using a set of values. Data is included in the aggregation only if a data field does not match one of the listed values. The following example calculates the sum of weatherdelay only for records in which the airportcode field is not LAX, ORD, or IAD.
TRANSFORMUse TRANSFORM to filter based on a derived date. To derive a date with TRANSFORM, you must already have a time attribute configured in your data source.
The following example calculates the sum of weatherdelay only for records in which the eventdate is for the previous period. In other words, if the visual is examining two weeks of data for weatherdelay, this calculation will provide data about the two weeks prior to that.

To work correctly, data must be available for the periods of time considered.

Row-Level Expressions

A row-level expression is a mathematical expression involving a single record (row) in the data. They are used to calculate derived fields but can also be used in custom metrics and admin-defined functions. Row-level expressions are created using attributes and metrics from the data and row-level functions.
Be careful not to create row-level expressions using fields in a data source that have had their field data type changed. Doing so may generate errors for the row-level expression. Instead, use the original field (with its original field type) to create a derived field of the field type you need and then use the new derived field in your row-level expressions.

Operators

Valid operators used in Self-Service Analytics are described below.

Distinct Counts

Distinct count functionality determines the number of unique values in a column or expression within a selected table by comparing all the records pulled from the data store by a data source configuration. When distinct counts are used, unique value results are returned when analyzing data. For example, distinct counts could return the number of:
  • Unique customers in a sales database
  • Unique UPC codes for a category of products
  • The number of trucks in a company’s fleet
For example, given a single collection and string field with the following three values:
  1. Apple
  2. Orange
  3. Apple
The distinct count returns 2, since there are only two distinct values (“Apple” and “Orange”), while an ordinary count returns 3 to reflect the total number of records. SQL-based connectors might produce a query that looks like this:
Support for this feature by connector is shown in the following table. Key:Y - Supported; N - Not Supported; N/A - not applicable
ConnectorSupported?Notes
Amazon RedshiftY
Amazon S3Y
Apache DrillY
Apache PhoenixY
Apache Phoenix Query Server (QS)Y
Apache SolrY
BigQueryYIf you need to access a BigQuery partition, explicitly include an alias for the built in partition column in your select clause, such as select *, _PARTITIONTIME as pt from projectId.datasetId.tableId.
Business Central JetY
Cloudera ImpalaYCloudera Impala connectors can receive only a single distinct count field in a query.
Cloudera SearchY
CouchbaseY
DremioY
Dundas BI (Managed)source-dependent
Elasticsearch 7.0Y
Elasticsearch 8.0Y
File Upload (Upload API)Y
HDFSY
HiveY
JiraY
MemSQLY
Microsoft SQL ServerY
MongoDBY
MySQLY
OpenSearchY
OracleY
PostgreSQLY
PythonY
Real Time SalesY
SalesforceY
SAP HanaY
SAP S/4HANAY
SAP IQY
Spark SQLY
SnowflakeY
TeradataY
TIBCO DVY
TrinoY
File Upload (Upload API)Y
VerticaY