# Metrics by Example > Find the AQL pattern that fits your question: by intent, by metric shape, or by copy-paste snippet. Built on a shared e-commerce schema. The Cookbook landing page. Three ways to find what you need: - **[By question](#by-question)**: "I want to do X" → the page that shows you how. - **[By metric shape](#by-metric-shape)**: what shape is the metric, and which function handles it. - **[Snippet gallery](#snippet-gallery)**: copy-paste AML for the most common patterns. ## Shared e-commerce schema Most examples on this page and across the Cookbook use this schema: **Models:** `users`, `orders`, `order_items`, `products`, `categories`, `merchants`, `cities`, `countries`. **Key relationships:** - `order_items` → `orders` (many:1) via `order_id` - `order_items` → `products` (many:1) via `product_id` - `orders` → `users` (many:1) via `user_id` - `users` → `cities` → `countries` (geographic chain) - `products` → `categories` (many:1) - `products` → `merchants` (many:1) ## By question When you know the *question* but not the *AQL feature*: | I want to… | Go to | |---|---| | Slice a metric by a dimension and add filters | [Learn → Filtering](/as-code/aql/learn/filtering), [Grouping](/as-code/aql/learn/grouping) | | Define a reusable metric or AQL dimension | [Learn → Defining a Metric](/as-code/aql/learn/defining-a-metric) | | Build a metric that spans multiple models | [Learn → Cross-Model Queries](/as-code/aql/learn/cross-model) | | Compute a ratio (e.g. completion rate) | [Learn → Defining a Metric](/as-code/aql/learn/defining-a-metric#metrics-compose), [Cookbook → Percent of Total](/as-code/aql/cookbook/aql-percent-of-total) | | Segment customers with a boolean flag (VIP, churned, etc.) | [Cookbook → LoD Patterns](/as-code/aql/cookbook/level-of-detail#use-case-3-customer-segmentation-flag--dimensionalize-for-filtering) | | Bucket records into tiers (deciles, quartiles) | [Cookbook → Ranking](/as-code/aql/cookbook/aql-rank#example-4-performance-tiers-with-ntile) | | Compute percent of total | [Learn → Level of Detail](/as-code/aql/learn/level-of-detail), [Cookbook → Percent of Total](/as-code/aql/cookbook/aql-percent-of-total) | | Aggregate already-aggregated data (avg of monthly totals, max of per-user metric) | [Learn → Nested Aggregation](/as-code/aql/learn/nested-aggregation), [Cookbook → Nested Aggregation](/as-code/aql/cookbook/aql-nested-aggregation) | | Rank items, with or without partitions | [Cookbook → Ranking](/as-code/aql/cookbook/aql-rank) | | Year-over-year, quarter-over-quarter comparison | [Learn → Time Comparisons](/as-code/aql/learn/time-comparisons), [Cookbook → Period Comparison](/as-code/aql/cookbook/aql-period-comparison) | | Smooth a time series with a moving average | [Cookbook → Moving Average](/as-code/aql/cookbook/aql-moving-average) | | Compound annual growth rate (CAGR) | [Cookbook → CAGR](/as-code/aql/cookbook/aql-period-comparison#method-5-compound-annual-growth-rate-cagr) | | Analyze customer order frequency / cohort distributions | [Cookbook → Customer Order Frequency](/as-code/aql/cookbook/aql-customer-order-frequency) | ## By metric shape Most metric questions resolve once you answer two questions: 1. **One aggregation, or several?** A single `sum`/`count`/`avg` is simple aggregation. Anything that aggregates an already-aggregated value (avg of monthly totals, percent of total, semi-additive sums) is multi-aggregation. 2. **What's the relationship between aggregations or filters?** Conditions, time periods, subgroups, accumulation, or nesting each map to a different AQL function. ### Single-aggregation metrics | Shape | Example | Where to go | |---|---|---| | Multiple tables/models | `order_items \| sum(order_items.quantity * products.price)` | [Cross-Model Queries](/as-code/aql/learn/cross-model) | | Filtered by condition | `avg(order_items.quantity) \| where(order_items.created_at matches @(last 3 months))` | [where()](/reference/aql/where) + [logical operators](/reference/aql/operator#logical-operator) | | Running / accumulated | `orders.total \| running_total(orders.created_at \| year())` | [Cumulative Metrics](/as-code/aql/cookbook/aql-cumulative-metrics), [window_sum](/reference/aql/window_sum) | | Different time period | `orders.count \| relative_period(orders.created_at, interval(-1 year))` | [Period Comparison](/as-code/aql/cookbook/aql-period-comparison) | ### Multi-aggregation metrics | Shape | Example | Where to go | |---|---|---| | Scalar combination of metrics | `sum(products.price) / count(products.id)` | Just write `metric_a / metric_b` | | Aggregations linked by a condition | `sum(balances.bank_balance) \| where(dim_dates.date == max(balances.record_date))` | [Semi-Additive Calculation](/as-code/aql/cookbook/aql-semi-additive-calculation) | | Calculated across different subgroups | `(order_items.total_sales*1.0) / (order_items.total_sales \| of_all(order_items))` | [Level of Detail Patterns](/as-code/aql/cookbook/level-of-detail), [Percent of Total](/as-code/aql/cookbook/aql-percent-of-total) | | Nested aggregations | `users \| group(month(users.sign_up_at)) \| select(count(users.id)) \| avg()` | [Nested Aggregation](/as-code/aql/cookbook/aql-nested-aggregation) | ## Snippet gallery Copy-paste-able definitions for the most common patterns. ### Simple aggregation Simple aggregation works by taking a table and an expression to evaluate over each row of that table. ```js title="Total Price of all Products after Discount" // `products` source table expression can be omitted products | sum(products.price * products.discount) ``` ```js title="Average Ordered Quantity of Order Items" avg(order_items.quantity) ``` ### Conditional aggregation ```js title="Average Ordered Quantity of Order Items over the Last 3 Months" avg(order_items.quantity) | where(order_items.created_at matches @(last 3 months)) ``` ### Aggregation with scalar functions ```js title="Average Price of Product" sum(products.price) / count(products.id) ``` ```js title="Total Actual Product Price" products | sum(products.price * products.discount) ``` ### Cross-model aggregation ```js title="Gross Merchandise Value (GMV)" order_items | select(order_items.quantity * products.price) | sum() // or more succinctly order_items | sum(order_items.quantity * products.price) ``` ```js title="GMV of refunded orders" order_items | sum(order_items.quantity * products.price) | where(orders.status != 'refunded') ``` See [Cross-Model Queries](/as-code/aql/learn/cross-model) for the full walkthrough. ### Cumulative metrics ```js title="Cumulative Sum of GMV" // orders.value = order_items | sum(order_items.quantity * products.price) sum(orders.value) | running_total() ``` ```js title="Running Percentage of Asia GMV over global GMV" (sum(orders.value) | running_total() | where(continents.name == 'Asia')) / (sum(orders.value) | running_total()) ``` See [Cumulative Metrics](/as-code/aql/cookbook/aql-cumulative-metrics) for the full walkthrough. ### Window functions ```js title="Running Sum of Count over Order Status" window_sum(count(orders.id), order: orders.status) ``` ### Multiple aggregation levels ```js title="Average GMV per Customer" orders | group(users.id) | select(sum(orders.value)) | avg() ``` See [Nested Aggregation](/as-code/aql/cookbook/aql-nested-aggregation). ### Custom relationships ```js title="Sum of revenue using custom relationships" sum(order_items.revenue) | with_relationships( order_items.order_id > orders.id, order_items.country_id > countries.id, ) ``` See [`with_relationships`](/reference/aql/with_relationships). ### Semi-additive metrics ```js title="Sum Bank Balance Any Customers" sum(balances.bank_balance) | where(dim_dates.date == ( max(balances.record_date) | of_all(balances.user_name) )) ``` See [Semi-Additive Calculation](/as-code/aql/cookbook/aql-semi-additive-calculation). --- In Holistics, data exploration is typically done through the UI, which generates AQL queries in the [`explore { }`](/reference/aql/explore-expression) format. The examples here show AML metric definitions. In practice, you define metrics once in AML and the UI generates the explore syntax for you.