AMQL Docs
Cookbook

Percent of Total

A detailed walkthrough on how to calculate the distribution of a metric using AQL.

Introduction

The Percent of Total analysis is a commonly used reporting technique that helps understand the contribution of each row value to the overall population.

In SQL, you have to divide your calculation into multiple CTEs (Common Table Expressions) and then cross-join those together to perform Percent of Total. Whereas with AQL, you can achieve this calculation in a more concise and reusable way by focusing on the business logic rather than the technical semantics.

Recommended Prerequisites

  • of_all: Exclude your metric from being evaluated against certain dimensions/grains.

High-level Flow

Suppose we want to see how each product's sales contribute to global sales.

To illustrate the calculation using AQL, we'll explore two different ways of performing it. First, we will break down the calculation into manageable steps or components. Then, we'll demonstrate how to write it as a single-line query.

Setup

To make it simple, we'll be working on the order_items modeling definition only with the following fields.

Measures and Metrics

You may see the use of measure in code snippets throughout this article. In AML, metrics defined inside data models are syntactically referred to as measure. We will use the word "metric" outside of code snippets to avoid confusions. Read more about Metrics here

We'll show two equivalent ways to define percent_of_total. Pick whichever style suits the metric:

Model order_items {
  ...
  dimension id {...}
  dimension product {...}
  dimension amount {...}

  measure total_sales {
    label: 'Total Sales'
    type: 'number'
    definition: @aql sum(order_items.amount) ;;
  }

  measure _total_sales_of_all {
    label: 'Total Sales of All'
    definition: @aql sum(order_items.amount) | of_all(order_items.id) ;;
    hidden: true
  }

  measure percent_of_total {
    label: "Percent of Total"
    type: 'number'
    definition: @aql (order_items.total_sales*1.0) / order_items._total_sales_of_all ;;
  }
}

Implementation

1. Define the aggregation

Calculate the total sales value for each product by defining the metric total_sales

Model order_items {
  ...

  measure total_sales {
      label: 'Total Sales'
      type: 'number'
      definition: @aql sum(order_items.amount) ;;
  }
}
explore {
  dimensions {
    products.name
  }
  measures {
    order_items.sales
  }
}
ProductTotal Sales
Chocolate 22187
Samsung Tablet 2101313
H&M T-shirt25194
Face Treatment4743
Adidas Shoes38901
Xbox102797
Jordan Shoes18760
Bunk Bed13893
AFC Biscuits2350
Sony Headphone 110665
Sofa 150334
Body Scrub211359
Flour 1800
Converse Shoes40575
Outdoor Sofa24999
Bathroom Mirror3960
Face Moisturizers4576
Wii24090
Cookies 26049
Face Cream17365
Nokia C187307
High Cabinet8432
Lacoste T-shirt21994
Body Cleanser161143
Reebox Shoes21231
Ticwatch 174019
KitKat 11037
Open in playground ↗

2. Define the aggregation with coarser level-of-detail

Total sales of all order items is also needed to be used as denominator for the percent of total. This metric can be definied by using of_all() metric function.

Model order_items {
  ...
  measure total_sales {...}

  measure _total_sales_of_all {
    label: 'Total Sales of All'
    type: 'number'
    definition: @aql order_items.total_sales | of_all(order_items) ;;
  }
}
explore {
  dimensions {
    products.name
  }
  measures {
    order_items.total_sales,
    order_items._total_sales_of_all
  }
}
ProductTotal SalesTotal Sales of All
Chocolate 221874391797
Samsung Tablet 21013134391797
H&M T-shirt251944391797
Face Treatment47434391797
Adidas Shoes389014391797
Xbox1027974391797
Jordan Shoes187604391797
Bunk Bed138934391797
AFC Biscuits23504391797
Sony Headphone 1106654391797
Sofa 1503344391797
Body Scrub2113594391797
Flour 18004391797
Converse Shoes405754391797
Outdoor Sofa249994391797
Bathroom Mirror39604391797
Face Moisturizers45764391797
Wii240904391797
Cookies 260494391797
Face Cream173654391797
Nokia C1873074391797
High Cabinet84324391797
Lacoste T-shirt219944391797
Body Cleanser1611434391797
Reebox Shoes212314391797
Ticwatch 1740194391797
KitKat 110374391797
Umbrella298554391797
Guess Jeans138814391797
10 Deep T-shirt93984391797
iPad 11302444391797
Open in playground ↗

3. Calculate the percent of total

Finally, the Percent of Total is determined by dividing the total_sales by _total_sales_of_all. Since _total_sales_of_all remains constant, the percent of total will adjust according to total_sales metric and its corresponding dimension

Model order_items {
  ...
  measure total_sales {...}
  measure _total_sales_of_all {...}

  measure percent_of_total {
    label: "Percent of Total"
    type: 'number'
    definition: @aql (order_items.total_sales*1.0) / order_items._total_sales_of_all ;;
  }
}

To maintain the decimal format for the percent of total metric, multiplying by 1.0 explicitly casts the left side to decimal.

explore {
  dimensions {
    products.name
  }
  measures {
    order_items.total_sales,
    order_items.percent_of_total
  }
}
ProductTotal SalesPercent of Total
Chocolate 221870.0498%
Samsung Tablet 21013132.307%
H&M T-shirt251940.5737%
Face Treatment47430.1080%
Adidas Shoes389010.8858%
Xbox1027972.3407%
Jordan Shoes187600.4272%
Bunk Bed138930.3163%
AFC Biscuits23500.0535%
Sony Headphone 1106650.2428%
Sofa 1503341.1461%
Body Scrub2113594.8126%
Flour 18000.0182%
Converse Shoes405750.9239%
Outdoor Sofa249990.5692%
Bathroom Mirror39600.0902%
Face Moisturizers45760.1042%
Wii240900.5485%
Cookies 260490.1377%
Face Cream173650.3954%
Nokia C1873071.9879%
High Cabinet84320.1919%
Lacoste T-shirt219940.5008%
Body Cleanser1611433.6692%
Reebox Shoes212310.4834%
Ticwatch 1740191.6854%
KitKat 110370.2361%
Umbrella298550.6798%
Guess Jeans138810.3161%
10 Deep T-shirt93980.2140%
Gucci T-shirt78260.1782%
Nike Shoes625291.4238%
Chips 2. Dried Fruit54350.1238%
Plant Pot219530.5000%
Sony Smart TV709611.6158%
Wrangler Jeans85620.1950%
Baking Soda 145360.1033%
iPhone X720531.6406%
TV Stand530581.2081%
Dining Chair 1310560.7071%
Xbox 360901422.0525%
Playstation 4395960.9016%
Single Bed23400.0533%
Oil 2265250.6040%
Apple Watch 11973754.4942%
Samsung Smart TV721281.6423%
iPhone 7770861.7552%
Kindle Fire 2690541.5723%
Kindle Fire 12032714.6284%
BlackBerry Key 11465083.3359%
Samsung Bluetooth Earphone847911.9307%
Essence Lotions185500.4224%
Flour 2121570.2768%
Oil 1173790.3957%
Face Mask114840.2615%
LG Smart TV678651.5453%
Samsung Galaxy 21272462.8974%
Bedroom Mirror238570.5432%
Fireplace739421.6836%
iPad 21088162.4777%
Chips 176730.1747%
Panasonic Smart TV1297502.9544%
Outdoor Lighting115680.2634%
Bathroom Slippers77640.1768%
Samsung Tablet 1506901.1542%
Shower curtains83470.1901%
Towels43630.0993%
Playstation 3326820.7442%
Sony Headphone 2357320.8136%
Samsung Galaxy 1459741.0468%
Smart Lighting146350.3332%
Open in playground ↗

4. Percent of total in one line

The entire steps described above can also be straightforwardly condensed into one single-line expression.

Model order_items {
  ...
  measure percent_of_total {
    label: "Percent of Total"
    type: 'number'
    definition: @aql (sum(order_items.amount) * 1.0) / (sum(order_items.amount) | of_all(order_items));;
  }
}
explore {
  dimensions {
    products.name
  }
  measures {
    order_items.total_sales,
    order_items.percent_of_total
  }
}
ProductTotal SalesPercent of Total
Chocolate 221870.0498%
Samsung Tablet 21013132.307%
H&M T-shirt251940.5737%
Face Treatment47430.1080%
Adidas Shoes389010.8858%
Xbox1027972.3407%
Jordan Shoes187600.4272%
Bunk Bed138930.3163%
AFC Biscuits23500.0535%
Sony Headphone 1106650.2428%
Sofa 1503341.1461%
Body Scrub2113594.8126%
Flour 18000.0182%
Converse Shoes405750.9239%
Outdoor Sofa249990.5692%
Bathroom Mirror39600.0902%
Face Moisturizers45760.1042%
Wii240900.5485%
Cookies 260490.1377%
Face Cream173650.3954%
Nokia C1873071.9879%
High Cabinet84320.1919%
Lacoste T-shirt219940.5008%
Body Cleanser1611433.6692%
Reebox Shoes212310.4834%
Ticwatch 1740191.6854%
KitKat 110370.2361%
Umbrella298550.6798%
Guess Jeans138810.3161%
10 Deep T-shirt93980.2140%
Gucci T-shirt78260.1782%
Nike Shoes625291.4238%
Chips 2. Dried Fruit54350.1238%
Plant Pot219530.5000%
Sony Smart TV709611.6158%
Wrangler Jeans85620.1950%
Baking Soda 145360.1033%
iPhone X720531.6406%
TV Stand530581.2081%
Dining Chair 1310560.7071%
Xbox 360901422.0525%
Playstation 4395960.9016%
Single Bed23400.0533%
Oil 2265250.6040%
Apple Watch 11973754.4942%
Samsung Smart TV721281.6423%
iPhone 7770861.7552%
Kindle Fire 2690541.5723%
Kindle Fire 12032714.6284%
BlackBerry Key 11465083.3359%
Samsung Bluetooth Earphone847911.9307%
Essence Lotions185500.4224%
Flour 2121570.2768%
Oil 1173790.3957%
Face Mask114840.2615%
LG Smart TV678651.5453%
Samsung Galaxy 21272462.8974%
Bedroom Mirror238570.5432%
Fireplace739421.6836%
iPad 21088162.4777%
Chips 176730.1747%
Panasonic Smart TV1297502.9544%
Outdoor Lighting115680.2634%
Bathroom Slippers77640.1768%
Samsung Tablet 1506901.1542%
Shower curtains83470.1901%
Towels43630.0993%
Playstation 3326820.7442%
Sony Headphone 2357320.8136%
Samsung Galaxy 1459741.0468%
Smart Lighting146350.3332%
Open in playground ↗

On this page