Power BI DAX IF Statement: Multiple Conditions, SWITCH, Blanks and 20+ Examples
Everything you need to write conditional logic in DAX: IF syntax, multiple conditions, nested IF vs SWITCH(TRUE()), blanks, text tests and a worked status measure with sample data.

The Power BI DAX IF function checks a condition and returns one value when it is true and another when it is false. The syntax is IF(<logical_test>, <value_if_true>, <value_if_false>). If you leave out the third argument, DAX returns BLANK. For three or more outcomes, SWITCH(TRUE(), ...) is usually cleaner than nesting IFs.
This guide is for Power BI developers and analysts who know the basics of measures and want conditional logic that is correct the first time. You will get copy-paste DAX for every common case: if else, multiple conditions, lists, text, blanks and errors, plus a full worked example you can rebuild in ten minutes.
Key takeaways
- IF takes a test, a true result and an optional false result; a missing false result gives BLANK.
- In a measure, the test must return one value, so wrap columns in an aggregation or use SELECTEDVALUE.
- Use
&&and||for multiple conditions andIN { }for lists. - Replace deep nested IFs with
SWITCH(TRUE(), ...)and put the most specific test first. - In DAX,
BLANK() = 0is TRUE; useISBLANKor the strict==operator when blanks matter. - Store repeated measures in variables (VAR) so each one is written once and easy to read.
In this guide
- What is the Power BI DAX IF statement?
- How to write your first DAX IF function
- IF statement in Power BI measure vs calculated column
- Power BI DAX IF multiple conditions
- Nested IF DAX vs SWITCH TRUE DAX
- Blanks: DAX IF null, not blank and blank then 0
- Text tests and DAX IFERROR
- Worked example: a sales status measure
- Performance, variables and IF.EAGER
- Common mistakes and fixes
- Conclusion and next steps
- FAQ
What is the Power BI DAX IF statement?
The power bi dax if statement is the basic tool for conditional logic in a semantic model. It looks at a condition, decides whether it is TRUE or FALSE, and returns the matching result. You can use it in measures, calculated columns, calculated tables and visual calculations, according to the IF function page on Microsoft Learn.
If you come from Excel, the dax if function will feel familiar. The big difference is context: Excel evaluates a formula for one cell, while DAX evaluates it for a row (in a column) or for a filter context (in a measure). Most IF problems in Power BI come from that difference, not from the syntax.
Syntax and arguments
IF ( <logical_test>, <value_if_true> [, <value_if_false>] )
- logical_test: any expression that evaluates to TRUE or FALSE, such as
[Total Sales] > 100000. - value_if_true: what to return when the test is TRUE. It can be a number, text, a date, another measure or another IF.
- value_if_false: optional. What to return when the test is FALSE. If you skip it, IF returns BLANK.
What data type does IF return?
If both results are numbers, IF converts them to one numeric type. For example, IF(condition, 1.0, 0) returns decimals only. If the results are different types, such as text and a number, IF returns a variant. A measure can live with that, but a calculated column cannot, and you lose number formatting and sorting. Keep both branches the same type.
How to write your first DAX IF function
Let us build a simple calculated column on a Product table that labels each product as Low or High price. You can follow along with any model that has a price column.
- Open Power BI Desktop and go to the Table view (or Data view).
- Select the Product table in the Data pane.
- On the Table tools ribbon, choose New column.
- Type the formula below in the formula bar and press Enter.
- Check a few rows to confirm the labels match the prices.
- Set the column's data type to Text if Power BI did not detect it.
Price Group =
IF ( 'Product'[List Price] < 500, "Low", "High" )
Use Shift + Enter in the formula bar to add line breaks. Formatting each argument on its own line costs nothing and makes long formulas much easier to debug.
Power BI DAX IF then else
People often search for power bi dax if then else because that is how many languages write it. DAX has no THEN or ELSE keywords. The second argument is your "then" and the third argument is your "else". The if ... then ... else words belong to Power Query M, which is a different language (more on that later).
Power BI DAX IF else without the third argument
A power bi dax if else formula does not always need the else part. When you leave it out, the result is BLANK, which is often exactly what you want in a measure because blank rows disappear from visuals.
Low Price Flag =
IF ( 'Product'[List Price] < 500, "Low" )
Here every product priced 500 or more gets BLANK instead of a label. In a calculated column that just looks empty; in a measure it hides the row in a table visual.
IF statement in Power BI measure vs calculated column
The same IF can behave very differently depending on where you put it. A calculated column runs once per row at refresh time and is stored in the model. A measure runs at query time, for every cell of every visual, inside the current filter context.
IF in a calculated column
Use a column when the result belongs to each row and you want to slice or filter by it, such as a price band, a customer segment or an "Is Weekend" flag. The test can read the current row's columns directly, as in the Price Group example above.
IF statement in Power BI measure
Writing an if statement in power bi measure is different because a measure has no "current row". It sees many rows at once, so the test has to compare aggregated values, usually other measures.
Total Sales = SUM ( Sales[Amount] )
Bonus =
IF ( [Total Sales] > 100000, [Total Sales] * 0.05 )
This returns a 5% bonus for any filter context (a salesperson, a month, a region) where sales pass 100,000, and BLANK everywhere else.
The "single value cannot be determined" error
If you reference a bare column in a measure, Power BI stops you with: A single value for column 'List Price' in table 'Product' cannot be determined. The measure does not know which of the many prices to test. You have three fixes:
- Aggregate it:
IF ( MAX ( 'Product'[List Price] ) < 500, "Low", "High" ). - Read the selected value:
IF ( SELECTEDVALUE ( 'Product'[Category] ) = "Bikes", ... ), which returns BLANK when more than one value is in context. - Iterate the rows:
SUMX ( Sales, IF ( Sales[Amount] > 1000, Sales[Amount] ) )tests each row, then adds the results.
For row-level filters like the last one, I prefer CALCULATE ( [Total Sales], Sales[Amount] > 1000 ). It gives the same total, it reads more clearly and the engine handles a filter more efficiently than a row-by-row IF.
Calculated column or measure: which to pick?
A simple rule: if you need to put the result on an axis, in a slicer or in a relationship, use a column. If the result depends on what the user selects (dates, regions, products), use a measure. A measure is also cheaper for large tables because it is not stored.
Power BI DAX IF multiple conditions: AND, OR, NOT and IN
Most real tests need more than one check. Power BI DAX IF multiple conditions are built with logical operators inside the first argument.
AND with &&
Both conditions must be TRUE. You can chain as many as you need.
Priority Customer =
IF (
'Customer'[Lifetime Sales] > 50000
&& 'Customer'[Orders] >= 10
&& 'Customer'[Country] = "Germany",
"Priority",
"Standard"
)
OR with ||
At least one condition must be TRUE.
Needs Review =
IF ( [Margin %] < 0.1 || [Return Rate] > 0.05, "Review", "OK" )
AND() and OR() functions vs the operators
DAX also has AND(a, b) and OR(a, b), but each takes exactly two arguments. Pass three and you get "Too many arguments were passed to the AND function". Nesting AND(AND(a, b), c) works but reads badly. Use the operators; they do the same thing and scale.
NOT
NOT flips a TRUE to FALSE. It is handy with functions that return TRUE or FALSE, such as NOT ISBLANK([Total Sales]) or NOT CONTAINSSTRING(...).
Power BI DAX IF in list with the IN operator
For a power bi dax if in list check, do not chain five OR conditions. The IN operator tests a value against a list in curly braces.
Region Group =
IF (
'Customer'[Country] IN { "Germany", "France", "Spain", "Italy" },
"EU core",
"Rest of world"
)
Not In List =
IF ( NOT ( 'Customer'[Country] IN { "Germany", "France" } ), "Other", "DE/FR" )
Text comparisons in DAX are not case-sensitive, so "germany" matches "Germany". That is usually helpful, but keep it in mind if your source data uses case to mean something.
Nested IF DAX vs SWITCH TRUE DAX
Once you need three or more outcomes, you have two choices: put IFs inside IFs, or use SWITCH. Microsoft's own SWITCH documentation suggests SWITCH as the cleaner way to avoid nested IF statements, and I agree.
Nested IF DAX
A nested if dax formula puts a second IF in the false branch of the first.
Price Band =
IF (
'Product'[List Price] < 500,
"Low",
IF (
'Product'[List Price] < 1500,
"Medium",
IF ( 'Product'[List Price] < 3000, "High", "Premium" )
)
)
It works, but every new band adds another level of brackets. At four or five levels, one misplaced parenthesis breaks the formula and it is hard to see where.
Switch true dax: the cleaner pattern
The switch true dax pattern passes TRUE() as the expression and then lists condition and result pairs. SWITCH returns the result of the first condition that is TRUE, and the last argument is the else value.
Price Band =
SWITCH (
TRUE (),
'Product'[List Price] < 500, "Low",
'Product'[List Price] < 1500, "Medium",
'Product'[List Price] < 3000, "High",
"Premium"
)
Same logic, one level, easy to extend. Order matters: SWITCH stops at the first TRUE test, so put the most specific or most important checks first. If you wrote < 3000 first, every product under 3,000 would be "High".
SWITCH with simple values
When you compare one expression with fixed values, use the shorter form with no TRUE():
Quarter Name =
SWITCH (
'Date'[Quarter Number],
1, "Q1 (Jan-Mar)",
2, "Q2 (Apr-Jun)",
3, "Q3 (Jul-Sep)",
4, "Q4 (Oct-Dec)",
"Unknown"
)
Which conditional function should you use?
| Function or pattern | Best for | Outcomes | Watch out for |
|---|---|---|---|
IF | One yes/no test | 2 (or 1 + BLANK) | Mixed return types become a variant |
Nested IF | Two or three bands, quick fixes | 3+ | Hard to read past 3 levels |
SWITCH(value, ...) | Matching one value to fixed values | Many | Only tests equality |
SWITCH(TRUE(), ...) | Ranges, mixed conditions, tiers | Many | First TRUE wins, so order tests carefully |
IFERROR | Catching a calculation error | 2 | Hides real problems; prefer DIVIDE for division |
COALESCE | Replacing BLANK with a default | First non-blank | Turning blanks into 0 shows every row in visuals |
Blanks: DAX IF null, not blank and blank then 0
DAX has no NULL. A missing value is BLANK, so a dax if null test is really a blank test. Blanks behave in ways that surprise people, and this is where most "my IF is wrong" questions come from.
The BLANK = 0 trap
In DAX, the normal equals sign treats BLANK as equal to 0 and to an empty string. So this formula labels a product with no sales as "Zero", which may not be what you meant:
Sales Check =
IF ( [Total Sales] = 0, "Zero", "Has sales" )
To tell them apart, use the strict equality operator ==, which returns TRUE only when both sides are the same type and value, or test for blank first with ISBLANK:
Sales Check =
SWITCH (
TRUE (),
ISBLANK ( [Total Sales] ), "No sales",
[Total Sales] == 0, "Zero (sales and returns cancel out)",
"Has sales"
)
Power BI DAX IF not blank
For a power bi dax if not blank check, wrap ISBLANK in NOT. This is useful when a calculation only makes sense where data exists:
Avg Price =
IF (
NOT ISBLANK ( [Total Quantity] ),
DIVIDE ( [Total Sales], [Total Quantity] )
)
DIVIDE already returns BLANK when the denominator is blank or 0, so the IF here is about clarity. It tells the next developer exactly when the measure should show a value.
Power BI DAX IF blank then 0
The power bi dax if blank then 0 request is one of the most common. Three ways that all work:
Sales or Zero v1 = IF ( ISBLANK ( [Total Sales] ), 0, [Total Sales] )
Sales or Zero v2 = COALESCE ( [Total Sales], 0 )
Sales or Zero v3 = [Total Sales] + 0
COALESCE is the cleanest. But think before you do it: a measure that never returns BLANK makes Power BI show every row, so a table of 5,000 products will list all 5,000, most with 0. A good habit is to show 0 only in cards and totals, or to limit it to rows that have a target with IF ( NOT ISBLANK ( [Total Target] ), COALESCE ( [Total Sales], 0 ) ).
Text tests and DAX IFERROR
Power BI DAX IF contains text
For a power bi dax if contains text test, use CONTAINSSTRING. It returns TRUE when the second text appears anywhere in the first, it is not case-sensitive and it accepts the * and ? wildcards.
Product Type =
IF ( CONTAINSSTRING ( 'Product'[Product Name], "bike" ), "Bike", "Accessory" )
If case matters, use CONTAINSSTRINGEXACT. If you need the position of the text rather than TRUE or FALSE, SEARCH (not case-sensitive) and FIND (case-sensitive) return a number. Give SEARCH a fourth argument so it does not error when the text is missing:
Has Discount Code =
IF ( SEARCH ( "promo", 'Sales'[Order Note], 1, 0 ) > 0, "Promo", "Full price" )
Other useful text tests: LEFT('Product'[SKU], 2) = "BK" for "starts with", and 'Product'[Color] IN { "Red", "Black" } for exact matches.
DAX IFERROR
DAX IFERROR returns a fallback value when an expression raises an error: IFERROR ( value, value_if_error ). It is tempting to wrap everything in it, but it hides real bugs and can slow measures down. For division, use DIVIDE, which handles zero and blank denominators for you:
-- avoid
Margin % = IFERROR ( [Profit] / [Total Sales], 0 )
-- better
Margin % = DIVIDE ( [Profit], [Total Sales] )
Keep IFERROR for the rare cases where an error is expected, such as converting messy text to a number with VALUE in a calculated column.
Worked example: a Power BI DAX IF status measure with sample data
Let us put everything together. You have sales and targets by region and want a status label plus a colour for conditional formatting. Here is the sample data:
| Region | Sales | Target | % of target | Expected status |
|---|---|---|---|---|
| North | 128,000 | 120,000 | 106.7% | Ahead |
| South | 96,000 | 100,000 | 96.0% | On track |
| East | 71,000 | 90,000 | 78.9% | Behind |
| West | (blank) | 80,000 | (blank) | No sales |
| Central | 54,000 | (blank) | (blank) | No target |
Step 1: the base measures
Total Sales = SUM ( Sales[Amount] )
Total Target = SUM ( Targets[Target] )
% of Target = DIVIDE ( [Total Sales], [Total Target] )
Step 2: the status measure
Sales Status =
VAR SalesAmt = [Total Sales]
VAR TargetAmt = [Total Target]
VAR Pct = DIVIDE ( SalesAmt, TargetAmt )
RETURN
SWITCH (
TRUE (),
ISBLANK ( SalesAmt ) && ISBLANK ( TargetAmt ), BLANK (),
ISBLANK ( TargetAmt ), "No target",
ISBLANK ( SalesAmt ), "No sales",
Pct >= 1, "Ahead",
Pct >= 0.95, "On track",
"Behind"
)
Walk through it. The first test keeps regions with no data at all blank, so they do not clutter the visual. The next two catch missing data before any maths. Then the percentage bands run from highest to lowest, and "Behind" is the else value. Check it against the table: South is 96%, which fails >= 1 and passes >= 0.95, so it is "On track".
Step 3: a colour measure for conditional formatting
Status Colour =
VAR Pct = DIVIDE ( [Total Sales], [Total Target] )
RETURN
SWITCH (
TRUE (),
ISBLANK ( Pct ), BLANK (),
Pct >= 1, "#1A9E5C",
Pct >= 0.95, "#F2C811",
"#D64545"
)
Apply it to a table or matrix in a few clicks:
- Add Region, Total Sales, Total Target and Sales Status to a table visual.
- In the Format pane, open Cell elements and pick the Sales Status series.
- Turn on Background color and select the fx button.
- Set Format style to Field value and choose the Status Colour measure.
- Select OK and check that each region gets green, yellow or red.
Hard-coded hex colours are fine for a first version. For a whole report, pick a palette once and reuse it everywhere; our free Power BI theme builder creates a theme JSON with good, neutral and bad colours that match your brand, so your IF colours and your charts agree.
Performance, variables and IF.EAGER
IF is rarely the slow part of a report, but a few habits keep conditional measures fast and readable.
Use variables for repeated measures
Without variables, a formula like IF ( [Total Sales] > [Total Target], [Total Sales] - [Total Target] ) mentions each measure twice. With VAR you write each one once, name it, and reuse it. That is easier to read, easier to change and gives the engine a clearer plan, as in the Sales Status example above.
Strict vs eager evaluation
By default, DAX tries to evaluate only the branch that the test picks (strict evaluation). The engine may still decide to compute both branches up front if it thinks that is faster. If you know that is better for your model, IF.EAGER forces the branches to be computed regardless of the condition. It has the same syntax as IF. Use it only after you have measured with Performance analyzer or DAX Studio; for most measures, plain IF is the right choice.
Push simple logic upstream
If a label depends only on columns in the same row and never on user selections, consider creating it in Power Query with M, where the syntax is if [List Price] < 500 then "Low" else "High". The column then compresses well, refreshes with the data, and keeps your DAX focused on measures. Keep it in DAX when it needs other tables, measures or filter context.
Common Power BI DAX IF mistakes and fixes
| Symptom | Cause | Fix |
|---|---|---|
| "A single value for column ... cannot be determined" | Bare column in a measure | Use MAX, SELECTEDVALUE or an iterator like SUMX |
| Blank rows show up as "Zero" | BLANK() = 0 is TRUE | Test ISBLANK first or use == |
| Visual suddenly lists every product | Measure returns 0 or text instead of BLANK | Return BLANK when there is no data |
| Everything lands in one SWITCH band | Broad test placed first | Order tests from most to least specific |
| "Too many arguments were passed to the AND function" | AND() takes only two arguments | Use && to chain conditions |
| Column cannot be created, variant data type | Branches return text and numbers | Return one type in every branch |
| Numbers sort like text in the visual | Numbers wrapped in quotes, e.g. "1" | Return numbers without quotes; format with FORMAT only for display |
Two more that do not throw errors but give wrong answers. First, totals: an IF measure tests the total row in its own context, so a grand total can show "Ahead" even when most regions are behind. If you want the total to sum the row results, iterate with SUMX ( VALUES ( Region[Region] ), ... ). Second, text with spaces: "North " with a trailing space does not equal "North". Clean it with TRIM in Power Query before you write the IF.
Conclusion and next steps
The Power BI DAX IF function is simple on the surface: a test, a true result and an optional false result. The skill is in the details around it: aggregating columns inside measures, using &&, || and IN for multiple conditions, switching to SWITCH(TRUE()) when the bands grow, and treating BLANK with care so your visuals stay clean.
Your next steps: rebuild the Sales Status and Status Colour measures on your own data, then replace one old nested IF in an existing report with SWITCH. For more DAX and design walkthroughs, browse our Power BI tutorials. If you want a ready-made report where these patterns are already wired up, have a look at our Power BI templates.
FAQ
How do I write an IF statement in Power BI DAX?
Use IF ( logical_test, value_if_true, value_if_false ), for example IF ( [Total Sales] > 100000, "High", "Low" ). Create it as a measure if it depends on filters, or as a calculated column if it labels each row.
Can a DAX IF have multiple conditions?
Yes. Combine tests with && (and) or || (or) inside the first argument, and use IN { ... } to compare against a list. The AND() and OR() functions also work but accept only two arguments each.
Is there an ELSE IF in DAX?
Not as a keyword. You either nest another IF in the false argument or, better, use SWITCH ( TRUE (), test1, result1, test2, result2, else_result ), which works like a chain of else-if checks.
How do I return 0 instead of blank in DAX?
Use COALESCE ( [Measure], 0 ) or IF ( ISBLANK ( [Measure] ), 0, [Measure] ). Be aware that a measure that never returns BLANK makes table visuals show every row, even ones with no data.
What is the difference between IF and SWITCH in DAX?
IF handles one test with two outcomes. SWITCH handles many outcomes in one flat formula, either by matching a value or, with TRUE() as the first argument, by checking conditions in order.
How do I check for null in DAX?
DAX uses BLANK instead of NULL, so test with ISBLANK ( value ). Avoid value = BLANK() when 0 is a valid value, because the regular equals sign treats BLANK and 0 as equal; use == for a strict check.
Why does my IF statement not work in a Power BI measure?
The most common reason is a bare column reference, which a measure cannot resolve to one value. Wrap the column in an aggregation such as MAX or SUM, use SELECTEDVALUE, or move the logic into a calculated column.
Does DAX IF evaluate both branches?
Usually it evaluates only the branch the test selects, but the engine may compute both if that is faster. IF.EAGER forces both branches to be calculated, which can help some DirectQuery or complex measures after testing.




