AMQL Docs

Try AMQL

One model, one dataset, one query. Enough to see how AML and AQL fit together, and a playground to run it in.

AMQL has two halves. AML describes your data: which tables exist, what their columns mean, how they relate. AQL asks questions of that description. This page walks through the smallest useful example of each, on an e-commerce schema with products and categories.

You don't need to install anything. Every snippet below runs in the AMQL playground. For guided exercises with instant feedback, there is also AMQL Learn.

1. Model a table

A Model wraps one table and names its columns as dimensions. The @sql body of each dimension is the column expression; {{ #SOURCE }} stands for the table.

products.model.aml
Model products {
  type: 'table'
  label: 'Products'
  data_source_name: 'demodb'
  table_name: 'demo.products'

  dimension id {
    label: 'ID'
    type: 'number'
    definition: @sql {{ #SOURCE.id }};;
  }

  dimension name {
    label: 'Name'
    type: 'text'
    definition: @sql {{ #SOURCE.name }};;
  }

  dimension category_id {
    label: 'Category ID'
    type: 'number'
    definition: @sql {{ #SOURCE.category_id }};;
  }
}

That is the whole modeling step for one table. The types are checked: a number dimension cannot be compared to a text one, and a typo in a dimension name is an error at authoring time, not a wrong number later.

2. Group models into a dataset

A Dataset says which models belong together and how they join. Here products and categories join through category_id.

ecommerce.dataset.aml
Dataset ecommerce {
  label: 'Ecommerce'
  data_source_name: 'demodb'

  models: [products, categories]

  relationships: [
    relationship(products.category_id > categories.id, true)
  ]
}

The > reads as "many to one": many products point at one category. From here on, any query can reach categories.name from a product without writing the join.

3. Ask a question

AQL reads left to right. Start from a model, pipe it through steps. This counts products per category:

Products per category
products | group(products.category_id) | select(products.category_id, count(products.id)) 
products->category_idcount_products->id
2528
418
2116
1421
314
1721
2223
2018
1013
711
1813
223
1616
1516
619
1211
1120
822
2412
Open in playground ↗

The Result tab is what comes back. The SQL tab is what AQL compiled it to, so you can always check the work.

4. Name it, reuse it

The moment a question is worth asking twice, give it a name. A measure is a named AQL expression on a model; it adapts to whatever it is grouped by.

Model products {
  // ... dimensions as above

  measure count_products {
    label: 'Count Products'
    type: 'number'
    definition: @aql count(products.id) ;;
  }
}

Now products | group(products.category_id) | select(products.category_id, products.count_products) gives the same answer, and so does grouping by categories.name, or by nothing at all. The definition is written once.

Where to go next

  • AQL in 30 minutes: the whole query language on one page.
  • AMQL Learn: interactive lessons, one concept at a time, with exercises you run in the browser.
  • AML overview: why a typed modeling language, and what else a model can hold.
  • Cookbook: period comparison, cohort retention, percent of total and more, each with runnable results.

On this page