Row level vs. aggregate
A row-level calculation runs once per row of the underlying data. [Sales] - [Cost] is row level: it computes profit for every row, then the view aggregates the result.
An aggregate calculation operates on already-aggregated values. SUM([Sales]) - SUM([Cost]) is aggregate.
For addition and subtraction the two give the same answer. For division they do not — SUM([Profit])/SUM([Sales]) is the correct profit ratio, while AVG([Profit]/[Sales]) averages per-row ratios and gives something else entirely.
The mixing error
SUM([Sales]) - [Cost] fails with cannot mix aggregate and non-aggregate arguments. Tableau can't compare one number per group against one number per row.
The fix is to make both sides consistent: SUM([Sales]) - SUM([Cost]), or wrap the row-level side in an aggregation like MIN() or ATTR() if you know it's constant within the group.
Conditional logic
IF [Sales] > 1000 THEN 'High' ELSEIF [Sales] > 500 THEN 'Medium' ELSE 'Low' END handles ranges. CASE [Region] WHEN 'East' THEN 1 WHEN 'West' THEN 2 ELSE 0 END is cleaner for matching a single field against discrete values, and generally performs better.
IIF(condition, then, else, [unknown]) is a compact two-branch form. ZN() wraps a nullable expression and returns zero instead of null, which prevents holes in charts and broken arithmetic.
Practical habits
Name calculations for what they mean, not how they work — Profit Ratio, not Calc1. Add comments with // for anything non-obvious. Keep one idea per calculated field; chaining three small clear calculations beats one unreadable expression, and Tableau optimises them together anyway.