SWITCH is the DAX function for evaluating a single expression against multiple possible values and returning different results for each match. It replaces chains of nested IF statements with a flat, readable structure that is easier to maintain and debug.
If you have ever written IF(condition1, result1, IF(condition2, result2, IF(condition3, result3, default))) and lost track of the parentheses, SWITCH is the fix. This guide covers the syntax, four practical patterns every analyst needs, the SWITCH-vs-IF decision, and the common mistakes that produce blank or unexpected results.
SWITCH Syntax
SWITCH(
<expression>,
<value1>, <result1>,
<value2>, <result2>,
...
[<else_result>]
)
The function evaluates <expression> once, then compares it against each <value> in order. When it finds a match, it returns the corresponding <result>. If no value matches and you provided an <else_result>, that is returned. If no value matches and there is no else clause, SWITCH returns blank.
Simple example — map a numeric score to a letter grade:
Grade = SWITCH(
TRUE(),
[Score] >= 90, "A",
[Score] >= 80, "B",
[Score] >= 70, "C",
[Score] >= 60, "D",
"F"
)
Key pattern: When you pass
TRUE()as the expression, SWITCH treats each value as a boolean condition. This is the most common usage pattern because it lets you write range-based logic (greater than, less than) rather than exact matches.
Pattern 1: Category Mapping
Map short codes or IDs to human-readable labels. This is the cleanest use case — a direct replacement for nested IFs.
Product Category Label = SWITCH(
Products[CategoryCode],
"ELEC", "Electronics",
"HOME", "Home & Garden",
"APP", "Apparel",
"FOOD", "Food & Beverage",
"Other"
)
Before (nested IF — hard to read):
Product Category Label =
IF(Products[CategoryCode] = "ELEC", "Electronics",
IF(Products[CategoryCode] = "HOME", "Home & Garden",
IF(Products[CategoryCode] = "APP", "Apparel",
IF(Products[CategoryCode] = "FOOD", "Food & Beverage",
"Other"
)
)
)
)
The SWITCH version is shorter, flatter, and easier to add new categories to. You just insert another value-result pair.
Pattern 2: Range-Based Bucketing
Use TRUE() as the expression to evaluate conditions in order. SWITCH returns the first match, so order matters — put the most restrictive conditions first.
Customer Segment = SWITCH(
TRUE(),
[Total Sales] >= 100000, "Enterprise",
[Total Sales] >= 50000, "Mid-Market",
[Total Sales] >= 10000, "SMB",
[Total Sales] > 0, "Individual",
"Prospect"
)
This is equivalent to a series of IF ... ELSE IF statements but without the nesting. Each condition is evaluated top to bottom, and the first one that returns TRUE wins.
Order matters: If you reversed the conditions so
[Total Sales] > 0came first, every customer with any sales would be classified as “Individual” and no customer would ever reach the Enterprise or Mid-Market tiers.
Pattern 3: Dynamic Measure Selection
Combine SWITCH with a parameter table or a slicer to let users pick which measure to display. This is a popular pattern for flexible report pages.
Step 1 — Create a disconnected table of measure names:
MeasureTable =
DATATABLE(
"MeasureName", STRING,
"SortOrder", INTEGER,
{
{"Total Sales", 1},
{"Total Profit", 2},
{"Total Quantity", 3},
{"Average Order Value", 4}
}
)
Step 2 — Use SWITCH in a measure to return the selected calculation:
Selected Measure = SWITCH(
SELECTEDVALUE(MeasureTable[MeasureName]),
"Total Sales", [Total Sales],
"Total Profit", [Total Profit],
"Total Quantity", [Total Quantity],
"Average Order Value", [Average Order Value],
BLANK()
)
When the user selects “Total Profit” from the slicer, the measure calculates [Total Profit]. When they switch to “Total Quantity”, it calculates that instead. One visual, four different metrics.
Pattern 4: Fallback Values for BLANK
Use SWITCH to provide default values when measures return blank — useful for dashboards where empty cells look broken.
Sales with Fallback = SWITCH(
TRUE(),
ISBLANK([Total Sales]), 0,
[Total Sales] < 0, 0,
[Total Sales]
)
This ensures the visual always shows a number rather than an empty space, while still preserving the original logic for valid values.
SWITCH vs IF: When to Use Which
| Criterion | SWITCH | Nested IF |
|---|---|---|
| 3+ conditions | ✅ Clean and flat | ❌ Deeply nested, hard to read |
| 1-2 conditions | Either works | ✅ Simpler for simple cases |
| Range-based logic | ✅ With TRUE() | ✅ Native |
| Exact-match mapping | ✅ Ideal use case | ⚠️ Works but verbose |
| Performance | ✅ Evaluates expression once | ⚠️ Evaluates each condition |
| Maintainability | ✅ Easy to add/reorder | ❌ Must track parentheses |
Rule of thumb: If you are writing more than two nested IFs, switch to SWITCH.
Common Mistakes
1. Forgetting the Else Clause
-- ❌ Problem: Returns BLANK if no condition matches
Status = SWITCH(
TRUE(),
[Days Overdue] > 30, "Critical",
[Days Overdue] > 7, "Warning"
)
-- ✅ Fix: Add an else clause
Status = SWITCH(
TRUE(),
[Days Overdue] > 30, "Critical",
[Days Overdue] > 7, "Warning",
"On Track"
)
2. Wrong Condition Order
-- ❌ Problem: First condition catches everything
Tier = SWITCH(
TRUE(),
[Sales] > 0, "Bronze",
[Sales] > 10000, "Silver",
[Sales] > 50000, "Gold"
)
-- Every row with Sales > 0 returns "Bronze"
-- ✅ Fix: Most restrictive conditions first
Tier = SWITCH(
TRUE(),
[Sales] > 50000, "Gold",
[Sales] > 10000, "Silver",
[Sales] > 0, "Bronze",
"None"
)
3. Using SWITCH Without TRUE() for Range Logic
-- ❌ Problem: SWITCH tries to match the Sales VALUE, not evaluate a condition
Tier = SWITCH(
[Sales],
[Sales] > 50000, "Gold", -- This compares [Sales] to TRUE/FALSE
"Other"
)
-- ✅ Fix: Use TRUE() as the expression
Tier = SWITCH(
TRUE(),
[Sales] > 50000, "Gold",
"Other"
)
4. Data Type Mismatch in Return Values
-- ❌ Problem: Mixing text and number return types
Result = SWITCH(
TRUE(),
[Score] > 90, "Excellent",
[Score] > 60, 1, -- Number in a text column
0
)
-- ✅ Fix: Keep return types consistent
Result = SWITCH(
TRUE(),
[Score] > 90, "Excellent",
[Score] > 60, "Pass",
"Fail"
)
FAQ
Q: Does SWITCH short-circuit (stop evaluating after the first match)?
Yes. SWITCH evaluates the expression once, then checks each value in order. When it finds a match, it returns the result immediately and does not evaluate remaining pairs. This makes it more efficient than nested IFs for long conditional chains.
Q: Can I nest SWITCH inside another SWITCH?
Yes, but it is usually a sign that you should restructure your logic. Consider using a separate calculated column or a mapping table instead. If you must nest, store the inner SWITCH result in a variable first using VAR for readability — see our DAX variables best practices guide.
Q: Is SWITCH faster than nested IF in DAX?
In most cases, yes. SWITCH evaluates the expression once and then does simple comparisons, while nested IF re-evaluates conditions at each level. The performance difference is small for 2-3 conditions but grows with longer chains. For large datasets, see our Power BI performance optimization guide.
Q: Can SWITCH work with wildcard or CONTAINS logic?
Not directly. SWITCH does exact comparison only. For pattern matching, combine SEARCH() or CONTAINSSTRING() with the TRUE() pattern:
Category = SWITCH(
TRUE(),
CONTAINSSTRING([Product Name], "laptop"), "Computers",
CONTAINSSTRING([Product Name], "phone"), "Mobile",
"Other"
)
Q: How many value-result pairs can SWITCH handle?
There is no hard limit in DAX, but extremely long SWITCH statements (50+ pairs) usually indicate you should use a mapping table with RELATED() or LOOKUPVALUE() instead. See our data modeling star schema guide for mapping table patterns.
What’s Next
- Master the foundational function behind most SWITCH measures: CALCULATE function
- Understand when conditions evaluate: Filter context vs row context
- Learn how to debug SWITCH logic gone wrong: DAX troubleshooting guide
- See how SWITCH pairs with ranking logic: DAX RANKX function