Calculated measures and dimensions
Often, dimensions are mapped to table columns and measures are defined as aggregations of top of table columns. However, measures and dimensions can also reference other members of the same or other cubes, use SQL expressions, and perform calculations involving other measures and dimensions. Most common patterns are known as calculated measures, proxy dimensions, and subquery dimensions.Calculated measures
Calculated measures perform calculations on other measures using SQL functions and operators. They provide a way to decompose complex measures (e.g., ratios or percents) into formulas that involve simpler measures. Also, calculated measures can help to use non-additive measures with pre-aggregations.Members of the same cube
In the following example, thecompleted_ratio measure is calculated as a division of
completed_count by total count. Note that the result is also multiplied by 1.0
since integer division in SQL would otherwise produce an
integer value.
completed_ratio, Cube will generate the following SQL:
Members of other cubes
If you havefirst_cube that is joined to second_cube, you can define a
calculated measure that references measures from both first_cube and second_cube.
When you query for this calculated measure, Cube will transparently generate SQL with
necessary joins.
In the following example, the orders.purchases_to_users_ratio measure references the
purchases measure from the orders cube and the count measure from the users cube:
users.purchases_to_users_ratio, Cube will generate the following SQL:
Proxy dimensions
Proxy dimensions reference dimensions from the same cube or other cubes. Proxy dimensions are convenient for reusing existing dimensions when defining new ones.Members of the same cube
If you have a dimension with a non-trivial definition, you can reference that dimension to reuse the existing definition and reduce code duplication. In the following example, thefull_name dimension references initials and
last_name dimensions of the same cube:
users.full_name, Cube will generate the following SQL:
Members of other cubes
If you havefirst_cube that is joined to second_cube, you can use a
proxy dimension to bring second_cube.dimension to first_cube as dimension (or
under a different name). When you query for a proxy dimension, Cube will transparently
generate SQL with necessary joins.
In the following example, orders.user_name is a proxy dimension that brings the
users.name dimension to orders. You can also see that there’s a join relationship
between orders and users:
orders.user_name and orders.count, Cube will generate the
following SQL:
orders.user_name only, Cube will figure out that it’s
equivalent to querying just users.name and there’s no need to generate a join in SQL:
Time dimension granularity
When referencing a time dimension of the same or another cube, you can specificy a granularity to refer to a time value with that specific granularity. It can be one of the default granularities (e.g.,year or week) or a custom granularity:
users.created_at, users.created_at__sunday_week, and
users.created_at__year dimensions, Cube will generate the following SQL:
Subquery dimensions
Subquery dimensions reference measures from other cubes. Subquery dimensions provide a way to define measures that aggregate values of other measures. They can be useful to calculate nested and filtered aggregates.See the following recipes:
- To learn how to calculate nested aggregates.
- To learn how to calculate filtered aggregates.
first_cube that is joined to second_cube, you can use a
subquery dimension to bring second_cube.measure to first_cube as dimension (or
under a different name). When you query for a subquery dimension, Cube will
transparently generate SQL with necessary joins. It works as a correlated
subquery but is implemented via joins for optimal
performance and portability.
In the following example, users.order_count is a subquery dimension that brings the
orders.count measure to users. Note that the sub_query parameter
is set to true on users.order_count. You can also see that there’s a join
relationship between orders and users:
avg_order_count measure performs an aggregation on order_count.
If you query for users.name and users.order_count, Cube will generate the
following SQL: