# AQL in 30 minutes > A skim-friendly tour of AQL. Each section is a 30-second preview with a deep link to the full Learn page. 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](/as-code/aql/#learning-roadmap)** on the AQL overview. ## Prerequisites AQL works against [AML](/reference/aml/) data models. You'll need a dataset with a few models and relationships defined. Quick example: ```aml 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)`. ```aml users | avg(users.age) // average age of all users ``` → [Full page](/as-code/aql/learn/pipe) ## 2. Filtering Two filters: - **`filter()`** narrows a table (like SQL `WHERE`). - **`where()`** narrows a metric (the filter rides with the aggregation). ```aml // 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](/as-code/aql/learn/filtering) ## 3. Grouping and aggregation `group()` collapses by a dimension; the next aggregator gives you one number per group. ```aml users | group(users.gender) | select(users.gender, count(users.id)) ``` → [Full page](/as-code/aql/learn/grouping) ## 4. Cross-model queries Because relationships are declared in the dataset, you reference columns from related models without writing joins: ```aml users | select(users.name, countries.name) ``` → [Full page](/as-code/aql/learn/cross-model) ## 5. Defining a metric Name an aggregation so you can reuse it everywhere: ```aml 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](/as-code/aql/learn/defining-a-metric) ## 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](/as-code/aql/learn/metric-context) ## 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. ```aml count(users.id) / (count(users.id) | of_all(countries)) ``` → [Full page](/as-code/aql/learn/level-of-detail) ## 8. Nested aggregation When the answer needs aggregation-of-aggregation (average monthly new customers, best month for revenue): ```aml users | group(users.created_at | month()) | select(count(users.id)) | average() ``` → [Full page](/as-code/aql/learn/nested-aggregation) ## 9. Time comparisons Shift a metric back in time and the comparison just becomes arithmetic: ```aml 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](/as-code/aql/learn/time-comparisons) ## Where to go next - **[Examples & Recipes](/as-code/aql/cookbook/metrics-by-example)**: copy-paste-ready patterns on a shared e-commerce schema. - **[Reference](/reference/aql/function)**: every function and operator.