Skip to main content

AQL in 30 minutes

This is the fast-track tour. Read top to bottom in about 5 minutes for a working mental model; click into any Learn page when you want the full treatment.

For the slow path with one concept per page, see the learning roadmap on the AQL overview.

Prerequisites

AQL works against AML data models. You'll need a dataset with a few models and relationships defined. Quick example:

Model users { dimension id {} dimension gender {} dimension age {} }
Model countries { dimension id {} dimension name {} }

Dataset e_commerce {
models: [users, countries]
relationships: [relationship(users.country_id > countries.id, true)]
}

1. The pipe operator

| chains operations left-to-right. x | f(args) is the same as f(x, args).

users | avg(users.age) // average age of all users

Full page

2. Filtering

Two filters:

  • filter() narrows a table (like SQL WHERE).
  • where() narrows a metric (the filter rides with the aggregation).
// Drop rows before aggregating
users | filter(users.gender == 'Female') | count(users.id)

// Bake the filter into a metric
count(users.id) | where(users.gender == 'Female')

Full page

3. Grouping and aggregation

group() collapses by a dimension; the next aggregator gives you one number per group.

users
| group(users.gender)
| select(users.gender, count(users.id))

Full page

4. Cross-model queries

Because relationships are declared in the dataset, you reference columns from related models without writing joins:

users | select(users.name, countries.name)

Full page

5. Defining a metric

Name an aggregation so you can reuse it everywhere:

Model users {
measure user_count {
definition: @aql count(users.id) ;;
}
}

Now users | group(users.gender) | select(users.gender, users.user_count) works, and the metric adapts to whatever the surrounding report groups by.

Full page

6. Metric context

A metric doesn't carry a fixed number. It evaluates against the surrounding dimensions, filters, relationships, and time window. The "advanced" parts of AQL are mostly about overriding one piece of that context.

Full page

7. Level of detail

Make a metric ignore some grouping (of_all), force a fixed grain (exclude), or turn an aggregation into a dimension (dimensionalize). Classic use: percent-of-total.

count(users.id) / (count(users.id) | of_all(countries))

Full page

8. Nested aggregation

When the answer needs aggregation-of-aggregation (average monthly new customers, best month for revenue):

users | group(users.created_at | month()) | select(count(users.id)) | average()

Full page

9. Time comparisons

Shift a metric back in time and the comparison just becomes arithmetic:

metric revenue_yoy_pct {
definition: @aql
safe_divide(
(revenue - (revenue | relative_period(orders.created_at, interval(-1 year)))) * 100,
revenue | relative_period(orders.created_at, interval(-1 year))
)
;;
}

Full page

Where to go next


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