BlogBusiness Intelligence

Advanced Tableau Calculated Fields: Table Calculations, LOD Expressions, and Performance

Obed Tsimi
Obed Tsimi
Founder & Senior Tableau Architect
·April 4, 202713 min read

Calculated fields in Tableau range from simple arithmetic to complex multi-level aggregations that require understanding when Tableau evaluates each calculation type. This guide covers table calculations, the full LOD expression toolkit, and the performance implications that determine which calculation type to use for which problem.

Tableau calculations exist at three distinct levels of evaluation, and the most common mistakes in Tableau development come from not understanding which level a calculation operates at and what data is visible to it. Understanding the evaluation order is not an academic exercise — it determines which calculation type can answer which analytical question.

The Evaluation Order

Tableau evaluates calculations in this order:

1. **Data source filters** — remove rows from the data before anything else

2. **Extract filters** — for extract data sources, filter before the extract is stored

3. **Context filters** — establish a filtered context used by FIXED LOD expressions

4. **Dimension filters** — filter rows visible to the current view

5. **FIXED LOD expressions** — compute at a fixed level, ignoring dimension filters (but respecting context filters)

6. **INCLUDE and EXCLUDE LOD expressions** — compute relative to the current view's level of detail, modified up or down

7. **Measure values, basic calculations** — compute at the row or aggregated level visible in the view

8. **Table calculations** — compute across the aggregated result set that Tableau has already computed

This order determines what data is available to each calculation type. A FIXED LOD expression does not see dimension filters — those are evaluated after it. A table calculation sees only the aggregated marks visible in the view — it cannot access individual row data.

Row-Level Calculations

Row-level calculations (basic calculated fields that are not LOD expressions) are evaluated at the row level of the data source — once per row, before any aggregation.

Example: a profit margin field:

[Profit] / [Sales]

This computes for each row. When you place it on a shelf, Tableau aggregates it — by default as AVG([Profit] / [Sales]), which is the average of the per-row ratios. This is different from SUM([Profit]) / SUM([Sales]), which is the aggregate profit margin. The two can produce very different numbers at different levels of granularity.

If you want the aggregate ratio, wrap it: SUM([Profit]) / SUM([Sales]). Or create a calculated field that is explicitly aggregated.

Row-level calculations are useful for: string manipulation on individual records, conditional categorisation of individual records (assigning a tier based on a row-level value), and date calculations on individual records (computing how many days since an order was placed).

Level of Detail (LOD) Expressions

LOD expressions allow you to compute aggregations at a level of granularity different from the current view's level of detail. They are the most powerful calculation type in Tableau and the most conceptually difficult.

### FIXED

FIXED computes the expression at the specified dimensions, regardless of what dimensions are in the view and regardless of dimension filters (but respecting context filters).

{ FIXED [Customer ID] : SUM([Sales]) }

This computes total sales per customer, for every customer, regardless of what dimensions are on the shelves. Even if the view is at the product level, this expression returns the customer's total sales. This allows comparisons like "this product's sales as a percentage of this customer's total sales."

A common FIXED use case: customer-level metrics on an order-level table.

{ FIXED [Customer ID] : MIN([Order Date]) }

This returns the first order date for each customer — the same value on every row that belongs to that customer. Use it to segment by cohort: which customers placed their first order in a given month?

Context filters matter for FIXED. If you create a context filter that restricts the data to "orders from 2024", a FIXED expression evaluates within that context — it only sees 2024 orders. This is useful when you want the LOD to respect a coarse filter (year) but ignore finer dimension filters (month, product category).

### INCLUDE

INCLUDE adds dimensions to the computation that are not in the current view.

{ INCLUDE [Order ID] : SUM([Quantity]) }

In a view at the customer/product level, this includes order IDs in the aggregation — computing the per-order quantity, then aggregating those up to the customer/product level using the LOD expression as an intermediate. This enables "average order size" computations in views that are not at the order level.

INCLUDE is less commonly used than FIXED, but it is the right tool when you need to aggregate at a finer grain than the view before aggregating up to the view grain.

### EXCLUDE

EXCLUDE removes dimensions from the computation that are in the current view.

{ EXCLUDE [Month] : SUM([Sales]) }

In a monthly view, this computes total sales ignoring the month dimension — producing the annual total for each row. Dividing the monthly sales by this value gives the percentage of annual total, visible on every monthly row.

This is the "percent of total" pattern in LOD form — more robust than a table calculation for the same purpose because it is not sensitive to which rows are visible in the current view.

Table Calculations

Table calculations are computed over the aggregated marks visible in the current view — after Tableau has computed everything else. They see the same data the user sees in the visualisation, not the underlying row-level data.

Table calculations include: RANK(), INDEX(), SIZE(), FIRST(), LAST(), WINDOW_SUM(), WINDOW_AVG(), LOOKUP(), and the RUNNING_ family of functions.

The key configuration for table calculations is the **Compute Using** setting — which dimensions define the addressing (which marks are being computed) and the partitioning (which groups of marks are computed independently).

**Addressing**: the dimensions across which the calculation moves. A RUNNING_SUM with "Table (across)" runs left to right across the columns. With "Table (down)" it runs top to bottom.

**Partitioning**: the dimensions that define independent groups. If the view is Product × Month and you compute a RUNNING_SUM partitioned by Product, each product gets its own independent running sum.

The most common table calculation mistake: the Compute Using setting does not match the analytical intent. Running totals computed across instead of down, or percentages computed per row instead of per column. Always verify the table calculation direction against the expected result.

### WINDOW_SUM and Moving Windows

WINDOW_SUM computes a sum over a window of marks:

WINDOW_SUM(SUM([Sales]), -2, 0)

This computes the 3-period rolling sum: the current period plus the 2 preceding periods. The arguments are relative offsets from the current mark. -2 means 2 marks before; 0 means the current mark.

WINDOW_AVG with the same offset arguments gives the rolling average — the 3-period moving average.

### LOOKUP: Accessing Other Marks

LOOKUP accesses the value of a calculation at a different mark:

LOOKUP(SUM([Sales]), -1)

Returns the sales value from the previous mark (in the current addressing direction). Used for period-over-period comparisons: current sales minus LOOKUP(SUM([Sales]), -1) gives the period-over-period change.

Performance Implications

**Row-level calculations**: evaluated once per row before aggregation. Simple row-level calculations are fast. Complex string operations or date calculations on large extracts can be slow if they prevent Tableau from pushing the aggregation to the data source.

**FIXED LOD expressions**: evaluated against the full data set at the specified dimensions. For live connections, Tableau generates a SQL query with the appropriate GROUP BY. For large tables with many rows, FIXED LODs can produce slow queries because they require scanning the full table. Precomputing frequently-used FIXED LOD aggregations in the data source or extract can significantly improve performance.

**Table calculations**: computed over the already-aggregated marks in the view. They are fast because they operate on a small result set (the marks in the view). The cost is that they cannot access row-level data — they see only what is aggregated in the view.

When a FIXED LOD can be replaced with a table calculation, the table calculation is usually faster. When a table calculation would require a specific view structure that is not appropriate for the analytical question, FIXED LOD is the right choice despite the cost.

Our Tableau consulting practice builds complex analytical environments with advanced calculation engineering — contact us to discuss your Tableau development requirements.

Get your data architecture audit in 30 minutes.

A former Microsoft data architect audits your data foundation, identifies your top priorities, and sends you a written plan. Free. No pitch.

Book a Call →