Dimensions
The columns you group by, filter on, and join across.
A dimension is a column — or a SQL expression over columns — that you group by, filter on, or join across. Dimension names are unique within a semantic model, but the same dimension name is deliberately declared on multiple models — that shared name is the join signal: two models join automatically when they each declare a dimension of the same name.
Two types
type | Use for |
|---|---|
categorical | Any non-time column — text, IDs, booleans, or a derived expression. Grouped and filtered on. |
time | A date/timestamp column. Requires time_grains. Enables time-series queries and rolling windows. |
Fields
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Unique within the model. Shared names across models are the cross-model join key. |
type | categorical | time | Yes | — |
description | string | Yes | What the dimension means; used to ground AI-generated queries. |
sql | string | No | Column name or SQL expression. Defaults to name when omitted. Set it when the physical column name differs from name, or to derive a value. |
time_grains | list | Required for time, forbidden for categorical | Any of day, week, month, quarter, year. |
certified | boolean | No (default false) | Marks the dimension as reviewed and trusted. |
must_be_grouped_or_filtered | boolean | No (default false) | Categorical only. See below. |
label | string | No | Display name. |
tags | list | No | For organizing and filtering. |
dimensions:
- name: order_date
type: time
sql: ordered_at # column differs from the dimension name
time_grains: [day, week, month, quarter]
description: Date the order was placed.
- name: signup_month
type: categorical
sql: FORMAT_DATE('%Y-%m', signup_date) # a derived expression
description: Month the user signed up (YYYY-MM).
- name: country
type: categorical
description: Two-letter country code.must_be_grouped_or_filtered
Some categorical columns cannot be safely aggregated across — for example a column that mixes per-row detail with pre-rolled-up totals, where summing every value would double-count. Set must_be_grouped_or_filtered: true on such a dimension.
Every query on a measure of that model must then either group by the dimension or filter it to a single value (dim = 'x', or a single-value IN). A query that does neither is rejected. Multi-value IN, !=, LIKE, and conditions under OR do not satisfy the requirement. This flag is valid only on categorical dimensions.
The sql field and pre-aggregations
When a dimension's sql differs from its name and that dimension is carried in a pre-aggregation, the rollup model must alias the column back to the dimension name (<sql> AS <name>). Queries read rollup columns by name, so an un-aliased source column would fail to resolve.