Semaphor
Semantic DomainsCalculated Fields

Overview

Create custom metrics, dimensions, and inline expressions without modifying your data source

Calculated fields let you create custom KPIs, derived groupings, and column transforms without modifying your underlying data source. They can be defined at multiple levels -- on a single card, shared across a dashboard sheet, or in a semantic domain template for organization-wide reuse.

Single-Entity vs Multi-Entity

Every calculated field falls into one of two categories based on how many datasets (entities) it references. This determines where the field is defined and how it behaves.

Inline Expressions (Single Entity)

When a calculation only involves fields from one dataset, it is defined as an inline expression directly on that dataset's field definition. The expression is a raw SQL transform -- no inputs mapping needed because all referenced fields belong to the same dataset.

datasets:
  - name: orders
    fields:
      metrics:
        - name: amount_usd
          label: "Amount (USD)"
          dataType: number
          expression: "amount_cents / 100"
          format: currency
      dimensions:
        - name: order_quarter
          label: "Order Quarter"
          dataType: date
          expression: "DATE_TRUNC('quarter', order_date)"

Use inline expressions for simple, single-dataset transforms like unit conversions, date truncations, CASE-WHEN bucketing, and string manipulation. Inline metric expressions are auto-wrapped in SUM() by default. Inline dimension expressions are row-level and appear in GROUP BY.

See Inline Expressions for full syntax and examples.

Root Calculated Fields (Multi-Entity)

When a calculation involves fields from multiple datasets -- or needs named inputs, nesting, or cross-dataset aggregation -- it is defined as a root calculated field in the calculatedMetrics or calculatedDimensions section of the domain template. Each input explicitly names the dataset it comes from.

calculatedMetrics:
  net_revenue:
    label: "Net Revenue"
    expression: "{total_sales} - COALESCE({total_returns}, 0)"
    inputs:
      total_sales: { dataset: orders, field: amount, aggregate: SUM }
      total_returns: { dataset: returns, field: amount, aggregate: SUM }

Use root calculated fields for cross-dataset KPIs (like net revenue from orders minus returns), nested metrics (profit margin using a profit metric), and calculated dimensions that need grain mappings for cross-dataset alignment.

See Calculated Metrics and Calculated Dimensions for full syntax.

How to Choose

Single dataset? Use an inline expression on the dataset field. Multiple datasets? Use a root calculated metric or root calculated dimension with named inputs.

For a detailed decision guide, see Choosing the Right Type.


Metrics vs Dimensions

Within both inline and root calculated fields, there are two roles: metrics (what you measure) and dimensions (what you group by).

MetricDimension
PurposeProduces an aggregated number (a KPI)Produces a row-level grouping value
SQL behaviorAppears inside aggregate functionsAppears in SELECT + GROUP BY
When computedAfter aggregation (combines totals, averages, counts)Before aggregation (transforms each row)
ExampleSUM(Revenue) / SUM(Cost)CASE WHEN {Amount} > 100 THEN 'Large' ELSE 'Small' END

Example: If you have 1,000 order rows:

  • A dimension like CASE WHEN {Amount} > 100 THEN 'Large' ELSE 'Small' END evaluates each of the 1,000 rows to categorize them
  • A metric like SUM(Revenue) / SUM(Cost) first computes SUM(Revenue) and SUM(Cost) across all rows, then divides the two results

This gives four field types in total:

TypeEntity scopeRoleDefined in
Inline Metric ExpressionSingle datasetMetricexpression on a dataset metric
Inline Dimension ExpressionSingle datasetDimensionexpression on a dataset dimension
Root Calculated MetricOne or more datasetsMetriccalculatedMetrics section
Root Calculated DimensionOne or more datasetsDimensioncalculatedDimensions section

Inline Metric Expressions

Inline metric expressions are also computed before aggregation -- they transform the raw column value (e.g., converting cents to dollars) and are then automatically wrapped in SUM(). This differs from root calculated metrics, which operate on already-aggregated values.

Looking for Running Totals or Moving Averages?

For analytical functions like running totals, moving averages, period-over-period deltas, and percent-of-total calculations, see Metric Transforms. Calculated fields define what to measure, while metric transforms analyze how those measurements change across rows.


When You Need Calculated Fields

  • Transform raw data -- Convert cents to dollars, truncate dates to quarters, or bucket values into categories (inline expression)
  • Standardize business KPIs -- Define profit margin, average order value, or conversion rate once and reuse across all dashboards (root calculated metric)
  • Create custom groupings -- Bucket order amounts into "Small / Medium / Large" or combine text fields (inline dimension expression or root calculated dimension)
  • Build cross-dataset metrics -- Compute net revenue (orders minus returns) by aggregating each dataset independently (root calculated metric)

Defining in the Domain Template

Define calculated fields in YAML/JSON as part of your domain template. This is the primary way to create domain-level fields for organization-wide reuse.

Inline expressions go directly on dataset fields:

datasets:
  - name: orders
    fields:
      metrics:
        - name: amount_usd
          expression: "amount_cents / 100"
          sourceField: amount_cents
          dataType: number
          format: currency

Root calculated fields go in their own sections:

calculatedMetrics:
  profit_margin:
    label: "Profit Margin %"
    expression: "{profit} / NULLIF({revenue}, 0) * 100"
    inputs:
      profit: { metric: profit }
      revenue: { metric: revenue }

See Calculated Metrics, Calculated Dimensions, and Inline Expressions for template syntax.

Domain-Level Calculated Fields

For organization-wide reuse, administrators define calculated fields directly in the domain template. Domain-level fields appear with a Domain badge in the field list and are read-only for dashboard users.


Best Practices

Naming:

  • Use descriptive names that explain what the field represents
  • Include units when relevant (e.g., "Revenue per Order (USD)")
  • Follow your organization's naming standards for consistency

Expressions:

  • Keep expressions simple -- break complex calculations into multiple calculated fields
  • Use NULLIF to prevent division by zero: {Revenue} / NULLIF({Orders}, 0)
  • Use COALESCE for null handling: COALESCE({Discount}, 0) * {Amount}
  • For complex multi-step calculations, use nested metrics

Choosing inline vs root:

  • Use inline expressions for simple single-dataset transforms -- keeps the definition close to the source data
  • Use root calculated fields when you need cross-dataset references, named inputs, nesting, or grain mappings

Documentation:

  • When defining domain-level calculated fields in the template, write clear label and description values covering what the field measures, how it's calculated, and any caveats

Getting Started

On this page