Tableau Course
Basic Calculations
Calculated fields let you create new Measures and Dimensions from the data already in your source — combining fields, applying formulas, and transforming text and dates without touching the original dataset. Every calculated field lives in the Data pane and behaves exactly like a native field once created.
Opening the Calculation Editor
To create a calculated field, go to Analysis menu → Create Calculated Field, or right-click any empty space in the Data pane and select Create Calculated Field. The calculation editor opens with a formula bar, a function reference panel on the right, and a validity indicator at the bottom. The indicator turns green when the formula is valid and red when it contains a syntax error. Tableau also shows a live error message explaining what is wrong.
Arithmetic Calculations
Arithmetic calculated fields combine numeric Measures using standard operators: +, -, *, /. The result is a new Measure that aggregates the same way as any other Measure in the Data pane.
Profit Ratio — Profit divided by Sales as a percentage
SUM([Profit]) / SUM([Sales])
For Furniture: SUM(Profit) = $18,451 ÷ SUM(Sales) = $741,999 = 0.0249 → 2.5%
Right-click the field in the Data pane → Default Properties → Number Format → Percentage to display as %.
Revenue per Order — Average order value
SUM([Sales]) / COUNTD([Order ID])
COUNTD() counts distinct values — it avoids double-counting orders that span multiple rows in the data.
Row-Level vs Aggregate Calculations
This distinction is the single most important concept in Tableau calculation writing. A row-level calculation runs on each individual row before any aggregation happens. An aggregate calculation runs after Tableau groups the data by the Dimensions in the view.
[Sales] - [Discount]
SUM([Sales]) / SUM([Profit])
String Functions
String calculated fields create new Dimension values by transforming, combining, or extracting text from existing fields. These are row-level calculations — they run on each row before aggregation.
Full Name — combining two string fields
[First Name] + " " + [Last Name]
Row 2: "Maria" + " " + "Garcia" → "Maria Garcia"
The + operator concatenates strings. A space literal " " is added between the two fields.
| Function | Syntax | Returns |
|---|---|---|
| LEN() | LEN([Product Name]) | Number of characters in the string |
| UPPER() / LOWER() | UPPER([City]) | All uppercase or all lowercase |
| LEFT() / RIGHT() | LEFT([Order ID], 4) | First or last N characters |
| MID() | MID([Order ID], 4, 6) | Substring from position 4, length 6 |
| CONTAINS() | CONTAINS([Product Name], "Chair") | TRUE if string contains the substring |
| REPLACE() | REPLACE([City], "New York", "NY") | Replaces all occurrences of a substring |
Date Functions
Date calculated fields extract parts of a date, calculate the difference between two dates, or offset a date by a given interval. These are among the most frequently used calculations in business dashboards.
Days to Ship — difference between Ship Date and Order Date
DATEDIFF('day', [Order Date], [Ship Date])
The first argument is the date part: 'day', 'week', 'month', 'year', 'hour', 'minute'.
Second argument is the start date, third is the end date. Result is always end minus start.
Order Year — extracting the year from a date field
DATEPART('year', [Order Date])
DATEPART returns a number. DATENAME returns the same value as a string — useful for labels.
Other date parts: 'month', 'quarter', 'week', 'day', 'weekday', 'hour'.
| Function | Example | Returns |
|---|---|---|
| DATEPART() | DATEPART('month', [Order Date]) | Month number as integer (1–12) |
| DATENAME() | DATENAME('month', [Order Date]) | Month name as string ("July") |
| DATEDIFF() | DATEDIFF('day', [Start], [End]) | Integer difference between two dates |
| DATEADD() | DATEADD('month', 3, [Order Date]) | Date offset by N date parts |
| TODAY() | DATEDIFF('day', [Order Date], TODAY()) | Current date — recalculates on each view load |
IF and CASE Logic Calculations
Logical calculations create new Dimension labels by evaluating conditions on each row. They are the standard way to create custom segments, tiers, and flags directly inside Tableau.
Profit Tier — segmenting orders into tiers by profit amount
IF [Profit] >= 500 THEN "High"
ELSEIF [Profit] >= 0 THEN "Positive"
ELSEIF [Profit] >= -200 THEN "Minor Loss"
ELSE "Major Loss"
END
Row: Profit = $45 → "Positive"
Row: Profit = -$88 → "Minor Loss"
Row: Profit = -$450 → "Major Loss"
Tableau evaluates conditions top to bottom and returns the first match. The ELSE clause catches all remaining rows.
Ship Mode Category — using CASE for exact string matching
CASE [Ship Mode]
WHEN "Same Day" THEN "Express"
WHEN "First Class" THEN "Express"
WHEN "Second Class" THEN "Standard"
WHEN "Standard Class" THEN "Standard"
ELSE "Unknown"
END
"Second Class" → "Standard" · "Standard Class" → "Standard"
CASE is cleaner than IF/ELSEIF when matching exact values of a single field. Use IF when conditions involve ranges, multiple fields, or boolean expressions.
The row-level versus aggregate distinction is where most Tableau beginners make their first serious calculation mistake. The error message "cannot mix aggregate and non-aggregate arguments" always means you have combined a raw field like [Sales] with an aggregated one like SUM([Profit]) in the same formula. The fix is always the same: wrap the raw field in the same aggregation — SUM([Sales]) / SUM([Profit]) — or remove the aggregation from the other field. For the Profit Ratio calculation, never write [Profit] / [Sales] at row level and expect a meaningful ratio — you will get the ratio for each individual line item, which Tableau then SUMs into a nonsensical total. Always write SUM([Profit]) / SUM([Sales]) for a ratio. The DATEDIFF function is the workhorse of operational dashboards — Days to Ship, Days Since Last Order, Contract Duration — these all come from DATEDIFF. Pair it with AVG() in the view to get the average days to ship per Region or Category without any additional calculated field work.
Practice Questions
1. Write the calculated field for Profit Ratio that returns the correct ratio at the Category level in a bar chart — not a per-row ratio.
2. Write the calculated field that returns the number of days between Order Date and Ship Date for each row.
3. Write the IF calculation that segments each row into four Profit Tiers: High (≥500), Positive (≥0), Minor Loss (≥-200), Major Loss (everything else).
Quiz
1. The formula [Profit] / SUM([Sales]) returns an error in Tableau. What is the correct fix?
2. A calculated field maps four exact Ship Mode string values to two category labels. Which logical function is the cleaner choice for this exact-value matching scenario?
3. A calculated field should return the number of days since each order was placed, updating automatically every day without any manual changes. Which formula achieves this?
Next up — Lesson 36: Table calculations — using RUNNING_SUM, WINDOW_AVG, RANK, and Percent of Total to compute values across the marks already in the view.