A normal sum({Sales}) is computed for whatever the visual groups by: per region in a chart by region,
per order in a table of orders. Sometimes you need a total at a fixed level instead, for example each
customer’s total sales, shown next to their orders or used to classify them. In QuickSight that is a
level-aware calculation: sumOver with the PRE_AGG level.
Copy and paste
Total sales of the row’s customer:
sumOver({Sales}, [{Customer}], PRE_AGG)
Save it as {Customer Total}. Then:
Customer tier, usable as a dimension:
ifelse(
{Customer Total} >= 1000, 'Key',
{Customer Total} >= 500, 'Regular',
'Small'
)
Each order’s share of its customer’s total:
sum({Sales}) / min({Customer Total})
Number of orders per customer:
countOver({Order ID}, [{Customer}], PRE_AGG)
Example
On the seven orders of the conditional logic guides,
Anna bought in both regions. In a table by Region and Customer, sum({Sales}) splits her sales by
region, and {Customer Total} keeps her whole total on both rows:
| Region | Customer | Sales | Customer Total |
|---|---|---|---|
| North | Anna | 700 | 1,200 |
| North | Bruno | 350 | 350 |
| South | Anna | 500 | 1,200 |
| South | Carla | 900 | 900 |
| South | Dario | 50 | 50 |
Grouped by the tier, with Count distinct of {Customer} and the sum of {Sales}:
| Tier | Customers | Sales |
|---|---|---|
| Key | 1 | 1,200 |
| Regular | 1 | 900 |
| Small | 2 | 400 |
Why PRE_AGG
PRE_AGG tells QuickSight to compute the sum before the visual aggregates anything, on the dataset
rows. Each row then carries its customer’s total, like a column of the dataset, and the visual’s own
grouping cannot change it. That has three consequences:
- The first argument is unaggregated:
{Sales}, notsum({Sales}). - It can be used as a dimension once it is wrapped in a row-level formula such as the tier. An
ordinary
ifelse(sum({Sales}) >= 1000, ...)cannot, because its value depends on the visual. - It can be filtered on. A filter
{Customer Total} >= 1000keeps all rows of the customers above 1,000, whatever the visual shows. In the example, only Anna’s three orders remain.
Aggregate it with min or max
In a visual the field still needs an aggregation, and every row of a customer holds the same value. AWS documents that level-aware window fields default to Min to avoid duplicates. Keep Min, Max or Average. Sum would add the customer total once per row: Anna’s North row would show 2,400, her total counted once for each of her two North orders.
Filters still apply
PRE_AGG is computed after the analysis filters on ordinary fields. With a filter on 2026 dates, the
customer total is the 2026 total; with a filter on the North region, Anna’s total becomes 700. When the
total must ignore the filters, use PRE_FILTER; the difference is explained in
PRE_AGG vs PRE_FILTER.
Or LAC-A
QuickSight also accepts a level in an aggregate function, sum({Sales}, [{Customer}]), called a
level-aware aggregate (LAC-A). It aggregates per customer and can be nested in a visual aggregation,
for example avg(sum({Sales}, [{Customer}])) for the average customer total per region. For tiers,
filters and per-row values, the sumOver form above is the documented route.
Checked against the Amazon Quick Sight documentation and the AWS Big Data Blog (October 2026). The example results were recomputed in DuckDB.