TABLEAU • CALCULATIONS AND METRICS

LOD & Filters — Combine LOD expressions with filters responsibly (context filters conceptually)

Master how Tableau's order of operations governs the interplay between LOD expressions and filters to produce correct analytics.

Historical Context & Motivation

Before the advent of modern visual analytics platforms, analysts working with SQL-based reporting tools frequently encountered a frustrating limitation: any filter applied to a query would uniformly restrict every aggregation in the result set. If you filtered to show only the year 2023, every sum, average, and count was scoped exclusively to 2023 data — there was no straightforward way to display a 2023-filtered metric alongside a grand-total metric computed across all years. Achieving such mixed-granularity results required subqueries, common table expressions, or window functions that many business users found inaccessible. Tableau set out to democratize analytics, but as its user base grew more sophisticated, the demand for calculations that could transcend or restrict the visible level of detail became impossible to ignore.

2003
Tableau Founded — VizQL Emerges
Pat Hanrahan and Chris Stolte commercialize VizQL, a visual query language that translates drag-and-drop actions into optimized database queries. Aggregation granularity is determined entirely by the dimensions on the shelf.
2009
Table Calculations Introduced
Tableau adds table calculations (RUNNING_SUM, RANK, WINDOW_AVG), enabling post-aggregation computation. These operate after filters, so they cannot override filter scope — a significant limitation for cross-granularity analysis.
2015
LOD Expressions Ship in Tableau 9.0
FIXED, INCLUDE, and EXCLUDE LOD expressions launch, allowing users to declare the exact grain of a calculation independently of the view. The relationship between LOD expressions and filters immediately becomes the most discussed topic in the Tableau community.
2018–Present
Context Filters & Pipeline Maturation
Tableau refines documentation around its order of operations (the 'query pipeline'). Context filters gain prominence as the mechanism to force dimension filters to apply before FIXED LOD computations, giving analysts fine-grained control over LOD scope.

The central question that LOD expressions address is deceptively simple: how do you compute a measure at a granularity that differs from what the current view shows, and how do filters interact with that computation? Understanding this interaction is not optional — misusing it produces silently incorrect numbers. The remainder of this lesson dissects Tableau's query pipeline, clarifies the role of context filters, and equips you to combine LOD expressions with filters responsibly.

Core Principles & Definitions

Before diving into the mechanics, it is essential to formalize the vocabulary. A Level of Detail (LOD) expression in Tableau is a calculated field whose aggregation granularity is explicitly declared in the formula itself, rather than being inferred from the dimensions present on the visualization shelves. The three LOD keywords — FIXED, INCLUDE, and EXCLUDE — each establish a different relationship between the formula's grain and the view's grain. Meanwhile, Tableau processes filters in a strict sequence known as the order of operations (or query pipeline), and the position of an LOD expression within that pipeline determines which filters can affect it.

1

FIXED LOD

Computes a measure at exactly the specified dimension(s), ignoring the view grain entirely. Syntax: { FIXED [Dim] : AGG(Measure) }. Because FIXED is evaluated early in the pipeline, most dimension filters do NOT affect it unless promoted to context filters.
2

INCLUDE LOD

Adds the specified dimension(s) to the view's grain, producing a finer level of detail. Syntax: { INCLUDE [Dim] : AGG(Measure) }. INCLUDE is affected by dimension filters because it is evaluated at or after the dimension filter stage.
3

EXCLUDE LOD

Removes the specified dimension(s) from the view's grain, producing a coarser level of detail. Syntax: { EXCLUDE [Dim] : AGG(Measure) }. Like INCLUDE, it respects dimension filters.
4

Context Filter

A dimension filter that is explicitly promoted (via right-click → 'Add to Context') so that it executes before FIXED LOD expressions. Conceptually, a context filter creates a temporary, filtered dataset on which all subsequent computations — including FIXED — operate.
5

Order of Operations (Query Pipeline)

Tableau's deterministic sequence: Extract Filters → Data Source Filters → Context Filters → FIXED LOD → Dimension Filters → INCLUDE/EXCLUDE LOD → Measure Filters → Table Calculations. Each stage consumes the output of the prior stage.
KEY TAKEAWAY
Think of the query pipeline as an assembly line in a factory. Raw materials (all rows) enter at one end. Each station (filter stage) removes or reshapes parts. A FIXED LOD expression is a worker stationed early on the line — it measures the material before most quality-control checkpoints (dimension filters) have run. If you want that worker to see only pre-approved material, you must move the quality checkpoint upstream by turning the filter into a context filter, effectively placing it before the FIXED station on the line.

Visual Explanation — Tableau's Order of Operations

The diagram shows Tableau's query pipeline from left-to-right and top-to-bottom. Notice that context filters (stage 3) execute before FIXED LOD (stage 4), while standard dimension filters (stage 5) execute after. This ordering is the single most important concept in this lesson.

The diagram above is the conceptual backbone of every decision you will make when combining LOD expressions with filters. When you drag a dimension to the Filters shelf and set it to show only a subset of values, Tableau by default places that filter at stage 5 — after FIXED LOD computations have already been resolved. This means a { FIXED [Region] : SUM([Sales]) } calculation will sum sales across all categories even if a dimension filter restricts the view to a single category. To make the FIXED expression respect that filter, you must promote the filter to a context filter (stage 3), effectively shrinking the dataset before the FIXED computation fires. INCLUDE and EXCLUDE expressions, in contrast, sit at stage 6, meaning they naturally respect dimension filters without any promotion.

How It Works — LOD Semantics and Filter Interaction

Formal Semantics of LOD Expressions

While Tableau does not expose SQL directly to the user, each LOD expression translates to a subquery or a window function under the hood. Understanding this translation clarifies why filter placement matters. Consider a view with [Category] on Rows and SUM([Sales]) on Columns. Adding a FIXED expression { FIXED [Region] : SUM([Sales]) } effectively generates a correlated subquery that groups by Region and joins the result back to every row in the main query. Because this subquery is logically evaluated before dimension filters, the subquery's WHERE clause includes only extract-level, data-source-level, and context-level filter predicates.

FIXED LOD — CONCEPTUAL SQL
SELECT Region, SUM(Sales) FROM DataSource WHERE [context_filter_predicates] GROUP BY Region
The WHERE clause contains only predicates from stages 1–3 (extract, data source, context). Standard dimension filter predicates are absent because they have not executed yet.
INCLUDE LOD — CONCEPTUAL SQL
SELECT [ViewDims], [IncludedDim], AGG(Measure) FROM filtered_data GROUP BY [ViewDims], [IncludedDim]
filtered_data represents the dataset after stages 1–5 (including dimension filters). The INCLUDE expression then adds [IncludedDim] to the GROUP BY, producing a finer grain. Because dimension filters have already run, INCLUDE naturally respects them.
EXCLUDE LOD — CONCEPTUAL SQL
SELECT [ViewDims \ ExcludedDim], AGG(Measure) FROM filtered_data GROUP BY [ViewDims \ ExcludedDim]
The backslash (\) denotes set difference. EXCLUDE removes [ExcludedDim] from the GROUP BY, yielding a coarser grain. Like INCLUDE, it respects dimension filters.

Context Filters — Conceptual Model

When you add a dimension filter to context, Tableau conceptually creates a temporary materialized table containing only the rows that pass the context filter predicate. All subsequent stages — including FIXED LOD — operate on this reduced table rather than the full data source. This is analogous to creating a CTE (Common Table Expression) in SQL: WITH ctx AS (SELECT * FROM DataSource WHERE [context_predicate]) and then running every other query against ctx. The performance implication is worth noting: because Tableau materializes this intermediate result, context filters can introduce latency on large datasets, but they guarantee semantic correctness when FIXED expressions must honor certain filter conditions.

Performance Note
Context filters cause Tableau to materialize a temporary table. On extracts (Hyper engine), the overhead is typically negligible. On live connections to row-store databases, context filters can significantly increase query time. Profile your workbook's performance before adding context filters liberally.

Detailed Breakdown — Filter Types and Their Pipeline Position

Tableau supports several filter types, each occupying a specific slot in the query pipeline. Misidentifying which filter type you are using is a common source of incorrect LOD results. The table below provides a comprehensive classification, including each filter's pipeline stage, its interaction with FIXED LOD, and practical use cases.

Filter types mapped to pipeline stages with LOD interaction flags
Filter TypePipeline StageAffects FIXED?Affects INCLUDE/EXCLUDE?
Extract FilterStage 1 — earliestYesYes
Data Source FilterStage 2YesYes
Context FilterStage 3Yes ✓Yes
Dimension Filter (standard)Stage 5No ✗Yes
Measure FilterStage 7NoNo
Table Calc FilterStage 8 — latestNoNo
Side-by-side comparison of a standard dimension filter (Scenario A) versus a context filter (Scenario B) on the same FIXED LOD expression. The decision flowchart at the bottom encodes the rule: if you need a dimension filter to constrain a FIXED computation, promote it to context.

The second diagram makes the practical implications concrete. In Scenario A, the FIXED expression calculates total sales per region across all categories because the Category filter has not yet executed when FIXED fires. The view shows only Furniture rows, but the FIXED value of $500K for East includes Technology and Office Supplies as well — a classic gotcha. In Scenario B, promoting Category to a context filter restricts the underlying data to Furniture rows before FIXED executes, yielding the correct $180K. The decision flowchart codifies a simple heuristic: whenever you combine FIXED LOD with a dimension filter and you intend the filter to constrain the FIXED computation, add the filter to context.

Worked Example — Customer Cohort Analysis with Context Filters

Suppose you are analyzing the Superstore dataset. Your goal is to build a bar chart showing the number of customers whose first purchase fell in each year, but only for customers who have purchased items in the Technology category. The first-purchase year is computed via a FIXED LOD expression on [Customer ID].

Cohort Count by First-Purchase Year, Filtered to Technology Customers
1
Step 1 — Define the FIXED LOD ExpressionCreate a calculated field called [First Purchase Year] with the formula: { FIXED [Customer ID] : MIN(YEAR([Order Date])) }. This returns the earliest order year for each customer, regardless of the dimensions in the view.
{ FIXED [Customer ID] : MIN(YEAR([Order Date])) }
2
Step 2 — Build the Initial ViewPlace [First Purchase Year] (converted to a discrete dimension) on Columns and COUNTD([Customer ID]) on Rows. At this point, the chart correctly shows how many customers made their first purchase in each year across the entire dataset.
3
Step 3 — Add a Category Filter (Standard) — Observe the BugDrag [Category] to the Filters shelf and select only 'Technology'. The bar chart now shows only Technology rows, but the FIXED expression was computed before this filter. This means a customer who first purchased a Furniture item in 2018 but also bought Technology in 2020 will appear in the 2018 cohort, since the FIXED value was computed on unfiltered data. Worse, customers who never purchased Technology may still have their FIXED value computed, though they are excluded from COUNTD due to the dimension filter. The cohort counts and years may be subtly wrong.
Bug: First-purchase year reflects all categories, not just Technology.
4
Step 4 — Promote Category to a Context FilterRight-click the [Category] filter pill on the Filters shelf and select 'Add to Context'. The filter pill changes color (gray background in Tableau's UI) indicating it is now a context filter. Tableau materializes a temporary table of only Technology rows. The FIXED expression is now re-evaluated on this reduced dataset: { FIXED [Customer ID] : MIN(YEAR([Order Date])) } now only considers Technology orders when determining each customer's first-purchase year.
Correct: First-purchase year now reflects the first Technology purchase.
5
Step 5 — ValidateSpot-check a specific customer. Suppose Customer ID 'AA-10315' first ordered Furniture in 2017 and first ordered Technology in 2019. Without the context filter, this customer appears in the 2017 cohort. With the context filter, they correctly appear in the 2019 cohort. The total customer count may also change, since customers who never bought Technology are now entirely excluded from the FIXED computation.

Strengths, Limitations, and Common Pitfalls

Comparison of filter types and LOD interactions
AspectStrengthLimitation / Pitfall
FIXED LODComputes at an exact grain independent of the view; essential for cohort analysis, benchmarks, and ratios against a fixed denominator.Ignores standard dimension filters, leading to silently incorrect values unless context filters are used. Can cause confusion when the same calculated field is reused across worksheets with different filter configurations.
Context FiltersProvide a clean mechanism to scope FIXED expressions; conceptually simple (shrink the dataset first).Introduce temporary table materialization, which may degrade performance on live connections. Over-reliance can mask design issues — sometimes restructuring the LOD expression is preferable.
INCLUDE/EXCLUDENaturally respect dimension filters, reducing the need for context filters. More intuitive for adding or removing granularity relative to the view.Cannot define an arbitrary grain — they only add to or subtract from the view's dimensions. Not suitable when the desired grain has no relationship to the view.
Table Calc FiltersExecute last in the pipeline, so they hide marks without altering underlying computations — useful for top-N filtering without distorting LOD values.Cannot affect any LOD expression. Often misunderstood by users who expect them to behave like dimension filters.
COMMON PITFALL
The most insidious bug in Tableau dashboards occurs when a developer builds a worksheet with a FIXED LOD expression, tests it without filters, confirms correctness, and then later adds a dimension filter on a dashboard-level action or parameter-driven filter. The FIXED values silently remain unchanged, producing metrics that look plausible but are wrong. Always audit every FIXED expression in a workbook whenever new filters are introduced.

Connection to Advanced Theory — Nested LOD, Parameters, and Sets

The interplay between LOD expressions and filters extends into more advanced Tableau patterns. Nested LOD expressions — where one LOD wraps another — follow the same pipeline rules, but the innermost expression is evaluated first, and its result is treated as a row-level value for the outer expression. Set-based filtering introduces another nuance: when a set is placed on the Filters shelf, it behaves as a dimension filter (stage 5), meaning it does not affect FIXED LOD unless the set filter is added to context. Similarly, parameter-driven filters implemented via calculated fields on the Filters shelf follow dimension filter semantics unless explicitly promoted.

From basic LOD-filter patterns to advanced techniques
PatternBasic Approach (this lesson)Advanced Extension
Scoping FIXEDPromote a single dimension filter to contextUse nested FIXED with an inner expression that pre-filters via a Boolean condition, avoiding context filters entirely
Dynamic granularityChoose INCLUDE or EXCLUDE based on static needsUse parameters to swap dimension references inside LOD expressions dynamically
Top-N within groupsTable calc filter to hide marksCombine FIXED with RANK table calc, then use set actions for interactive top-N that respects LOD
Cross-database LODSingle data source LODLOD across blended data sources (limited — FIXED only works within primary source)

As you progress into Tableau Prep, Tableau Server (now Tableau Cloud), and embedded analytics, the LOD-filter interaction remains unchanged — the query pipeline is a constant across all Tableau products. Building a solid mental model of this pipeline now will pay dividends when you encounter row-level security filters (which operate at the data source level, stage 2) or initial SQL (which runs before even extract filters). Each mechanism is simply another station on the same assembly line.

Practice Problems

PROBLEM 1CONCEPTUAL
Explain why a { FIXED [Customer ID] : SUM([Sales]) } expression is not affected when you filter the view to show only the 'West' region using a standard dimension filter. Reference the query pipeline stages in your answer.
PROBLEM 2BASIC CALCULATION
You have the following calculated field: { FIXED [Region] : AVG([Profit]) }. Your view has [Category] on Rows and the FIXED field on Columns, with a standard dimension filter on [Segment] = 'Consumer'. What value does the FIXED field show — the average profit per region for Consumer only, or for all segments? What single change makes it respect the Segment filter?
PROBLEM 3INTERMEDIATE
You want to display each product's sales as a percentage of its category's total sales, and you want a dimension filter on [Region] to correctly restrict both the numerator and the denominator. Write the calculated field, specify which LOD type to use, and state whether a context filter is necessary.
PROBLEM 4APPLIED
A product manager asks you to build a dashboard with a Region quick filter. One chart shows average order value by sub-category; another shows average customer lifetime value (LTV), computed as { FIXED [Customer ID] : SUM([Sales]) }. The Region filter should scope both charts. Describe your filter design, including whether you use context filters, dashboard filter actions, or another approach, and justify your choice from a performance and correctness standpoint.
PROBLEM 5CRITICAL THINKING
Consider the expression { FIXED : COUNTD([Customer ID]) } (a FIXED expression with no dimension specified). This computes the grand total of distinct customers. Now suppose you have a standard dimension filter on [Category] = 'Furniture' and a context filter on [Region] = 'East'. What value does this expression return? Generalize your answer: describe the rule governing a FIXED expression with an empty dimension list and its interaction with each filter type.

Summary

Tableau's LOD expressionsFIXED, INCLUDE, and EXCLUDE — allow you to compute measures at granularities that differ from the visualization's level of detail. The critical insight is that these expressions occupy specific positions within Tableau's order of operations (query pipeline): FIXED is computed at stage 4, before standard dimension filters (stage 5), while INCLUDE and EXCLUDE are computed at stage 6, after dimension filters. This ordering means FIXED expressions are immune to dimension filters by default.

To make a dimension filter constrain a FIXED expression, promote it to a context filter (stage 3), which materializes a temporary table before FIXED fires. Use context filters deliberately: they ensure correctness but may incur a performance cost on live connections. Always audit FIXED expressions whenever new filters are added to a workbook, and prefer INCLUDE or EXCLUDE when the desired granularity can be expressed as an addition to or subtraction from the view's dimensions, since these types naturally respect dimension filters without requiring context promotion.

Varsity Tutors • Tableau • LOD & Filters — Combine LOD expressions with filters responsibly (context filters conceptually)