Tableau Course
FIXED, INCLUDE, and EXCLUDE — In Depth
With the three LOD keywords understood individually, this lesson builds the patterns that appear in professional dashboards: customer segmentation, cohort analysis, ratio-to-parent calculations, and the rules that govern how LOD expressions interact with filters and aggregations.
FIXED with Multiple Dimensions
A FIXED expression can declare more than one Dimension, separated by commas. The aggregation then computes at the intersection of all declared Dimensions — just as a view-level aggregation computes at the intersection of all Dimensions currently in the view.
Sales per Customer per Region — two-Dimension FIXED
{ FIXED [Customer Name], [Region] : SUM([Sales]) }
John Smith, East → $2,100 on every row where Customer = John Smith AND Region = East.
John Smith, West → $2,100 on every row where Customer = John Smith AND Region = West.
Adding more Dimensions narrows the granularity — fewer rows share the same value.
FIXED with no Dimension — grand total on every row
{ FIXED : SUM([Sales]) }
Grand total = $2,297,201 stamped on every row regardless of Category, Region, or any other Dimension.
Common use: SUM([Sales]) / { FIXED : SUM([Sales]) } gives each row's share of the overall grand total — a percent-of-grand-total at row level that a table calculation cannot easily replicate when filters are involved.
Cohort Analysis — FIXED in Practice
Cohort analysis groups customers by the month they first purchased and then measures their behaviour in subsequent months. It requires two FIXED expressions working together — the acquisition date and the months-since-acquisition offset — both attached to every order row.
Step 1 — Acquisition Month per Customer
{ FIXED [Customer Name] : MIN([Order Date]) }
John Smith's earliest order: 2021-03-14 → stamped on all his rows.
Maria Garcia's earliest order: 2022-08-02 → stamped on all her rows.
Name this field "First Order Date". Truncate to month in the view for cohort grouping.
Step 2 — Months Since Acquisition per Order
DATEDIFF('month',
{ FIXED [Customer Name] : MIN([Order Date]) },
[Order Date]
)
— His March 2021 order → Month 0 (acquisition month)
— His June 2021 order → Month 3
— His January 2022 order → Month 10
Place First Order Date (truncated to month) on Rows and Months Since Acquisition on Columns. Use COUNTD([Customer Name]) or AVG(Sales) as the metric — this builds the standard cohort retention grid.
Cohort Grid — Labelled Mockup
| Cohort | Month 0 | Month 1 | Month 2 | Month 3 | Month 6 |
|---|---|---|---|---|---|
| Jan 2022 | 248 | 186 | 154 | 131 | 98 |
| Feb 2022 | 312 | 241 | 198 | 167 | 122 |
| Mar 2022 | 289 | 210 | 172 | 140 | 88 |
| Apr 2022 | 195 | 148 | 119 | 97 | 61 |
INCLUDE — Computing at a Finer Granularity Than the View
INCLUDE temporarily adds the Dimension you declare to the current view's Dimensions, computes the aggregation at that finer level, and then lets the outer aggregation summarise those finer results back up to the view level. The key phrase is finer than the view — INCLUDE always drills down, never up.
The most common situation where INCLUDE is needed: you want the average of a group total, not the average of individual rows. These are very different numbers and a plain AVG() cannot distinguish between them without INCLUDE.
Average Customer Spend per Category — INCLUDE in practice
AVG( { INCLUDE [Customer Name] : SUM([Sales]) } )
Technology: Customer A → $1,200 · Customer B → $840 · Customer C → $3,100 …
Furniture: Customer A → $520 · Customer D → $2,300 · Customer E → $680 …
Step 2 — Outer AVG averages those per-customer totals within each Category row:
Technology avg customer spend = $1,480
Furniture avg customer spend = $890
Office Supplies avg customer spend = $610
If the view is then filtered to show only East Region, INCLUDE respects that filter — it only includes customers from East in its computation.
Maximum single-order value per Sub-Category — INCLUDE with MAX
MAX( { INCLUDE [Order ID] : SUM([Sales]) } )
Outer MAX: returns the largest single-order total within the Sub-Category.
In a view at Sub-Category level — Chairs: largest single order = $4,200 · Tables: $3,840
This is impossible with a plain MAX([Sales]) which returns the largest individual line-item value, not the largest order total — a very different and far smaller number.
INCLUDE — How the Two-Step Evaluation Works
| Category | Customer | SUM(Sales) |
|---|---|---|
| Technology | Cust A | $1,200 |
| Technology | Cust B | $840 |
| Technology | Cust C | $3,100 |
| Furniture | Cust A | $520 |
| Furniture | Cust D | $2,300 |
| Category | AVG Customer Spend |
|---|---|
| Technology | $1,713 |
| Furniture | $1,410 |
Furniture: (520+2300)/2 = $1,410
INCLUDE vs FIXED — Choosing Between Them
| Scenario | Use INCLUDE | Use FIXED |
|---|---|---|
| Filter sensitivity | Result should change when a dimension filter is applied | Result should stay constant regardless of view filters |
| Direction | Drilling finer than the view — adding a Dimension to the calculation | Fixing at an exact level — regardless of the view |
| Typical pattern | AVG( { INCLUDE [fine grain] : AGG } ) — average of group totals at view level | { FIXED [grain] : AGG } — stamp a value on every row for a Dimension member |
| Example | Avg customer spend shown per Category — updates when Region filter changes | Customer lifetime value attached to every order row — ignores Region filter |
Customer Segmentation — FIXED for Bin Assignment
A common segmentation pattern computes a customer-level metric with FIXED and then uses an IF/CASE calculation to assign each customer to a segment. Because the FIXED value is the same on every row for a given customer, the segment label is also consistent across all their rows — making it safe to use as a filter or Color Dimension without double-counting.
Customer Lifetime Segment — combining FIXED with IF logic
IF { FIXED [Customer Name] : SUM([Sales]) } >= 5000 THEN "High Value"
ELSEIF { FIXED [Customer Name] : SUM([Sales]) } >= 1000 THEN "Mid Value"
ELSE "Low Value"
END
Customer lifetime Sales $1,000–$4,999 → "Mid Value" on every row.
Customer lifetime Sales below $1,000 → "Low Value" on every row.
Because the FIXED total is the same for all of a customer's rows, the segment label is stable. Dragging this field to Color on a scatter plot cleanly segments every order by customer tier with no mixing of labels within a customer.
Ratio to Parent — EXCLUDE for Share of Category
A ratio-to-parent calculation divides each Sub-Category's Sales by its parent Category's total. EXCLUDE removes Sub-Category from the aggregation to get the Category-level denominator — without leaving the current view or adding a separate table calculation.
Sub-Category Share of Category Sales
SUM([Sales]) / { EXCLUDE [Sub-Category] : SUM([Sales]) }
Tables (Furniture): $206K / $742K = 27.8%
Bookcases (Furniture): $114K / $742K = 15.4%
Phones (Technology): $330K / $827K = 39.9%
The denominator changes automatically for each Category — Furniture rows use the Furniture total, Technology rows use the Technology total. A table calculation Percent of Total would instead compute share relative to all Sub-Categories across all Categories.
LOD Expressions in the Filter Order
Understanding where LOD expressions sit in the filter execution order explains nearly every unexpected result when LOD and filters interact.
Nested LOD Expressions
LOD expressions can be nested inside other LOD expressions or inside regular aggregation functions. A nested LOD first computes the inner expression at its declared granularity, then the outer expression aggregates those results at its own level. The cohort months-since-acquisition calculation from earlier is an example — DATEDIFF() wrapping a FIXED expression.
Average Customer Lifetime Value by Region — nested FIXED inside AVG
AVG( { FIXED [Customer Name] : SUM([Sales]) } )
Outer AVG: when the view shows Region on Rows, averages the per-customer lifetime totals within each Region.
East: average customer LTV = $3,240 · West: $2,980 · Central: $2,410 · South: $2,150
This is the correct average LTV per Region. A plain AVG([Sales]) would instead average individual order line values — far lower and not meaningful as an LTV metric.
The filter order diagram is worth memorising: FIXED computes after context filters but before dimension filters. That single fact explains every LOD debugging scenario you will encounter. If FIXED gives wrong results when a filter is applied, the fix is always to promote that filter to context. The ratio-to-parent EXCLUDE pattern — SUM([Sales]) / { EXCLUDE [Sub-Category] : SUM([Sales]) } — replaces complex Percent of Total table calculation workarounds once you know it exists.
Practice Questions
1. A view shows Region on Rows. Write the LOD expression that returns the average customer lifetime Sales value per Region — not the average order line value.
2. Write the calculated field that returns each Sub-Category's Sales as a share of its parent Category's total Sales — where the denominator changes automatically per Category.
3. Write the LOD expression that returns the overall grand total of Sales on every single row — regardless of Category, Region, or any other Dimension in the view.
Quiz
1. A FIXED expression computing customer lifetime Sales returns the same value when a Region dimension filter is applied and when it is removed. At which point in the filter execution order does FIXED compute, and what is the fix?
2. A cohort analysis grid needs Acquisition Month on Rows and Months Since Acquisition on Columns. Which two calculated fields are required and what does each compute?
3. You want a calculated field showing each Category's Sales as a percentage of the overall grand total — not just of the visible view. Which LOD expression provides the correct grand total denominator?
Next up — Lesson 40: Advanced LOD patterns — set-based analysis, survey data normalisation, and using LOD expressions to solve problems that require multiple levels of aggregation simultaneously.