Tableau Course
Level of Detail Expressions
A Level of Detail (LOD) expression lets you compute an aggregation at a specific granularity — independent of the Dimensions currently in the view. Where a regular calculated field always aggregates at the view level, an LOD expression fixes the aggregation level you want regardless of what the view shows.
The Problem LOD Expressions Solve
Imagine you want to show each order's Sales alongside the average Sales for that customer — on the same row-level view. A regular SUM([Sales]) in a view grouped by Order gives you each order's total. But AVG([Sales]) also computes at order level when the view is at order level. You need the average computed at Customer level, then brought back down to Order level for comparison. A regular calculated field cannot do this. An LOD expression can.
LOD Syntax — The Three Keywords
Every LOD expression follows the same structure: a keyword in curly braces, a Dimension declaration, a colon, and an aggregation. The keyword controls how the declared Dimensions relate to the view's Dimensions.
{ FIXED [Dimension] : AGG([Measure]) }
{ INCLUDE [Dimension] : AGG([Measure]) }
{ EXCLUDE [Dimension] : AGG([Measure]) }
FIXED — Compute at an Exact Granularity
FIXED computes the aggregation at exactly the Dimensions you specify — ignoring whatever Dimensions are in the view. The result is the same regardless of what the view shows. FIXED is the most commonly used and most powerful LOD type.
Total Sales per Customer — computed at Customer level, attached to every row
{ FIXED [Customer Name] : SUM([Sales]) }
For every order row belonging to "Maria Garcia" whose total = $1,850 — returns $1,850 on all her rows.
Now you can use this field in a view at order level to compare each order's Sales against its customer's lifetime total — impossible with a regular aggregation.
First Order Date per Customer — the customer's acquisition date
{ FIXED [Customer Name] : MIN([Order Date]) }
This enables cohort analysis: group customers by the month of their first order, then measure their subsequent purchasing behaviour. Without FIXED, computing first order date at customer level in a view showing individual orders is not possible with a regular MIN().
FIXED — Data Flow Mockup
| Order ID | Customer Name | Sales (row) | FIXED SUM(Sales) |
|---|---|---|---|
| CA-2023-001 | John Smith | $820 | $4,200 |
| CA-2023-047 | John Smith | $1,540 | $4,200 |
| CA-2023-088 | John Smith | $1,840 | $4,200 |
| NY-2023-012 | Maria Garcia | $650 | $1,850 |
| NY-2023-091 | Maria Garcia | $1,200 | $1,850 |
INCLUDE — Add a Dimension to the View Level
INCLUDE computes at a finer granularity than the view by temporarily adding the specified Dimension to the view's Dimensions. The result is then aggregated back up to the view level. INCLUDE is useful when you want to compute something at row or sub-group level and then average or summarise the results in the view.
Average Order Value per Customer — average of per-customer totals shown at Category level
AVG( { INCLUDE [Customer Name] : SUM([Sales]) } )
The outer AVG() then averages those per-customer totals at the Category level shown in the view.
Result: for each Category bar, the height shows the average total spend of customers who bought in that Category — not the average order line value, which would be far lower.
EXCLUDE — Remove a Dimension from the View Level
EXCLUDE computes at a coarser granularity than the view by temporarily removing the specified Dimension from the calculation. This is the right choice when you need a subtotal or grand total alongside detail — such as showing each Sub-Category's Sales alongside the total for its Category, without adding a separate grand total row.
Category Total alongside Sub-Category detail — benchmark comparison
{ EXCLUDE [Sub-Category] : SUM([Sales]) }
— Chairs (Sub-Category of Furniture): EXCLUDE returns $741,999 — the total for all of Furniture
— Tables (Sub-Category of Furniture): EXCLUDE also returns $741,999
— Phones (Sub-Category of Technology): EXCLUDE returns $827,456 — the total for all of Technology
Every Sub-Category row now shows its parent Category's total alongside it — useful as a reference line or for computing each sub-category's share of its parent.
FIXED vs INCLUDE vs EXCLUDE — Side by Side
| Keyword | Granularity | Respects View Filters | Classic Use Case |
|---|---|---|---|
| FIXED | Exactly the declared Dimensions — ignores view | No — ignores dimension filters. Respects context filters and data source filters. | Customer lifetime value, cohort first-order date |
| INCLUDE | View Dimensions plus the declared Dimension | Yes | Average of per-customer totals shown at a higher level |
| EXCLUDE | View Dimensions minus the declared Dimension | Yes | Parent category total alongside sub-category detail |
FIXED and Dimension Filters — The Important Caveat
FIXED LOD expressions are computed before dimension filters are applied in Tableau's execution order. This means a FIXED expression will include data from rows that a dimension filter would otherwise remove. For example, a FIXED Customer Sales total will include all of a customer's orders — even if the view is filtered to show only the East Region.
To make a FIXED expression respect a filter, promote that filter to a context filter. Context filters run before FIXED LOD expressions in the execution order, so the FIXED calculation operates only on the context-filtered data. This is the most common LOD debugging step in real-world workbooks.
LOD expressions are the point where Tableau goes from a visualisation tool to an analytical engine. The two most important real-world FIXED patterns are customer lifetime value — { FIXED [Customer Name] : SUM([Sales]) } — and cohort acquisition date — { FIXED [Customer Name] : MIN([Order Date]) }. Together these two fields enable the most requested dashboard analysis in e-commerce and SaaS: cohort retention. You group customers by their first purchase month, then track their average subsequent spend by months-since-acquisition. None of this is possible without FIXED. The filter interaction is the gotcha every analyst hits on their first FIXED calculation. If your FIXED total does not change when you apply a Region filter, it is because FIXED ignores dimension filters by design. Add the Region filter to context — grey pill, right-click → Add to Context — and the FIXED calculation immediately recalculates within the filtered data. INCLUDE and EXCLUDE are used far less frequently than FIXED in practice, but EXCLUDE is the elegant answer whenever a stakeholder asks to show each row alongside its group subtotal for comparison. One EXCLUDE expression replaces what would otherwise require a data blend, a join, or a table calculation workaround.
Practice Questions
1. Write the LOD expression that returns each customer's first-ever Order Date — attached to every row for that customer — so customers can be grouped into acquisition cohorts.
2. A view shows Category and Sub-Category on Rows with SUM(Sales) on Columns. Write the LOD expression that returns each Sub-Category's parent Category total — so each Sub-Category row can be compared to its Category benchmark.
3. A FIXED LOD expression showing customer lifetime Sales does not change when a Region filter is applied. How do you make it respect the Region filter?
Quiz
1. A view shows individual orders. You need each order row to also display its customer's total Sales across all orders — not just the Sales of that one order. Which LOD keyword computes this correctly?
2. A FIXED LOD expression returns the same values whether a Region filter is active or not. What explains this behaviour and how is it corrected?
3. A view has both Category and Sub-Category on Rows. You want a field that returns the total Sales for the parent Category on every Sub-Category row. Which LOD keyword and Dimension declaration achieves this?
Next up — Lesson 39: FIXED, INCLUDE, and EXCLUDE in depth — advanced LOD patterns including cohort analysis, customer segmentation, and nested LOD expressions.