Skip to main content

Where to define AQL expressions

You can write AQL in four places: on a model, on a dataset, as a standalone Metric, or ad-hoc inside a dataset exploration. The right home depends on scope (which models the expression touches) and reusability (who else needs it).

Decision table

TypeExampleBest homeWhy
Simple aggregation / single-model metricTotal ordersModel: measureCalculation lives where the data does; reusable wherever the model is reused
Single-model dimension transformAge group from users.ageModel: dimensionTravels with the model
Cross-model metricRevenue per userDataset: metricNeeds the dataset's relationships to join
Cross-model dimensionCustomer segment based on purchasesDataset: dimensionSame reason: needs the join graph
Metric reused across multiple datasetsGMV shared by Sales, Finance, and Marketing datasetsStandalone MetricDefined once, attached to any dataset via extend
One-off analysisQ4 sales spike investigationAd-hoc in explorationNot worth persisting

How the four placements compare

Model measure / dimensionDataset metric / dimensionStandalone MetricAd-hoc in exploration
ScopeOne modelMultiple models in the datasetAny dataset that includes itSingle exploration
Reuses across datasets✅ Wherever the model is used❌ Bound to one dataset✅ Attach to any dataset❌ Single exploration
Visible to end users✅ Once attached to a datasetOnly the exploration's viewers
Persists✅ In source-controlled AML✅ In source-controlled AML✅ In source-controlled AMLOnly if saved as a report
Who editsData team (modeling layer)Data team (modeling layer)Data team (modeling layer)Anyone with explore access

On a model

When the calculation only touches one model, put it on the model (as a measure for aggregation, or dimension for per-row transform). It then travels with the model wherever it's reused.

Model orders {
data_source_name: 'main'

dimension id { type: 'number', primary_key: true }
dimension amount { type: 'number' }
dimension status { type: 'text' }
dimension created_at { type: 'datetime' }

// Aggregation → measure
measure total_revenue {
type: 'number'
definition: @aql sum(orders.amount) ;;
}

// Per-row transform → dimension
dimension is_completed {
type: 'truefalse'
definition: @aql orders.status == 'completed' ;;
}
}

On a dataset

When the expression spans multiple models, define it at the dataset level. The dataset is where the relationships live, so it's the only place AQL can resolve cross-model joins.

Dataset ecommerce {
models: [orders, order_items, products, users]
relationships: [
relationship(order_items.order_id > orders.id, true),
relationship(order_items.product_id > products.id, true),
relationship(orders.user_id > users.id, true),
]

metric revenue_per_user {
type: 'number'
definition: @aql
safe_divide(
order_items | sum(order_items.quantity * products.price),
count_distinct(users.id)
)
;;
}

dimension customer_segment {
model: users
type: 'text'
definition: @aql
case(
when: (sum(orders.amount) | dimensionalize(users.id)) > 10000, then: 'VIP',
when: (sum(orders.amount) | dimensionalize(users.id)) > 1000, then: 'Regular',
else: 'New'
)
;;
}
}
AQL metric defined inside a dataset

As a standalone Metric

When the same metric is needed across multiple datasets, declare it as a top-level Metric object. The definition lives independently of any dataset, and each dataset attaches it via extend. Change the definition once, and every dataset that references it picks up the update.

metrics.aml
Metric gmv {
label: "GMV (Gross Merchandise Value)"
type: "number"
definition: @aql order_items | sum(order_items.quantity * products.price) ;;
format: "[\$\$]#,###0"
}

Metric total_orders {
label: "Total Orders"
type: "number"
definition: @aql count(orders.id) ;;
}

Then attach the standalone metrics to any dataset that needs them:

sales.dataset.aml
Dataset sales_with_metrics = sales.extend({
metric gmv: gmv
metric total_orders: total_orders
})

The same gmv definition can be attached to a finance dataset, a marketing dataset, and so on. It's a single source of truth for the calculation. For organizing groups of related metrics (e.g. a thematic PartialDataset of finance metrics), see Implement Reusable Metric Store.

Ad-hoc in an exploration

For a one-off question, write the AQL directly in a dataset exploration. The expression persists only if you save the exploration as a report. Good for quick analysis or for users who don't have modeling-layer access.

tip

If you don't see the option to define AQL expressions and your account signed up before April 19, 2024, you may need to enable AQL for your datasets.

See also


Open Markdown
Let us know what you think about this document :)