Skip to main content

Composability in metric views

This page explains how composability works in metric views and provides examples that show you how to compose logic by building on dimensions, measures, and joins within a single view.

Overview

Metric views are composable, which means you can define layered, reusable logic. Instead of writing every definition from scratch, you can create new ones that build on existing dimensions and measures.

With composability, you can:

  • Reference previously defined dimensions in new dimensions
  • Reference any dimension or previously defined measures in new measures
  • Reference columns from joins defined in the metric view

Composability helps you avoid duplication, streamline metric definitions, and support more complex analysis without requiring raw SQL each time.

Metric composability

Composability is the principle of building complex metrics by reusing simpler, foundational measures. Instead of writing and maintaining complex, nested SQL logic for every derived KPI, you define the core "atomic" measures once and then reference them in other, more sophisticated calculations. This approach dramatically improves consistency, auditability, and maintenance of your semantic layer.

The foundation of composability is the MEASURE() function, which allows a measure definition to reference any other measure defined within the same metric view.

Define measures with composability

Composability is implemented in the measures section of the metric view YAML.

Measure Type

Description

Example

Atomic

A simple, direct aggregation on a source column. These form the building blocks.

SUM(o_totalprice)

Composed

An expression that mathematically combines one or more other measures using the MEASURE() function.

MEASURE(Total Revenue) / MEASURE(Order Count)

Example: Average Order Value (AOV)

To calculate Average Order Value (AOV), you need two measures: Total Revenue and Order Count.

YAML
source: samples.tpch.orders

measures:
# Total Revenue
- name: total_revenue
expr: SUM(o_totalprice)
comment: The gross total value of all orders.
display_name: 'Total Revenue'

# Order Count
- name: order_count
expr: COUNT(1)
comment: The total number of line items or orders.
display_name: 'Order Count'

# Composed Measure: Average Order Value (AOV)
- name: avg_order_value
# Defines AOV as Total Revenue divided by Order Count
expr: MEASURE(total_revenue) / MEASURE(order_count)
comment: Total revenue divided by the number of orders.
display_name: 'Avg Order Value'

In this example, if the definition of total_revenue changes (e.g., if a filter to exclude tax is added), the avg_order_value automatically inherits that change, ensuring the AOV metric remains consistent with the new business rule.

Composability with conditional logic

You can use composability to create complex ratios, conditional percentages, and growth rates without relying on window functions for simple period-over-period calculations.

Example: Fulfillment Rate

To calculate the Fulfillment Rate (Fulfilled Orders / Total Orders), you first define the measure for completed orders using a FILTER clause.

YAML
source: samples.tpch.orders

measures:
# Total Orders (denominator)
- name: total_orders
expr: COUNT(1)
comment: Total volume of orders regardless of status.

# Fulfilled Orders (numerator)
- name: fulfilled_orders
expr: COUNT(1) FILTER (WHERE o_orderstatus = 'F')
comment: Only includes orders marked as fulfilled.

# Composed Measure: Fulfillment Rate (Ratio)
- name: fulfillment_rate
expr: MEASURE(fulfilled_orders) / MEASURE(total_orders)
display_name: 'Order Fulfillment Rate'
format:
type: percentage # Using semantic metadata to format as a percent

Best practices for using composability

  1. Define atomic measures first: Always establish your fundamental measures (SUM, COUNT, AVG) before defining any measures that reference them.
  2. Use MEASURE() for consistency: Always use the MEASURE() function when referencing another measure's calculation within an expr. Don't try to manually repeat the aggregation logic (for example, avoid SUM(a) / COUNT(b) if measures for both the numerator and denominator already exist).
  3. Prioritize readability: The expr for a composed measure should read like a mathematical formula for the KPI. For example, MEASURE(Gross Profit) / MEASURE(Total Revenue) is clearer and easier to audit than a single complex SQL expression.
  4. Combine with semantic metadata: After composing a ratio, use semantic metadata (as shown in the fulfillment_rate example) to automatically format the result as a percentage or currency for downstream tools. See Use semantic metadata in metric views.