Control Structures (if/then/else)
M's sole branching construct — if/then/else — and how to write clean conditional logic.
M has exactly one branching construct: if...then...else. There are no switch statements, ternary operators, or pattern matching. Every conditional decision in M flows through this single structure.
Basic Syntax
if [Region] = "East" then "Eastern" else "Other"The test expression must evaluate to a logical value (true or false). Unlike JavaScript or Python, M does not have "truthy" or "falsy" values — passing a number or text as the condition raises an error.
if 1 then "yes" else "no" // Error: logical value expectedMulti-Branch Conditions
Since there is no elseif keyword, you nest if expressions in the else clause:
if [Region] = "East" then "Eastern Division"
else if [Region] = "West" then "Western Division"
else if [Region] = "North" then "Northern Division"
else "Other"The else clause is required — every if must have a corresponding else. This ensures the expression always produces a value, which is consistent with M's functional design.
Using if in Columns
The most common use of if is inside Table.AddColumn to create calculated columns:
Table.AddColumn(
Sales,
"PriceCategory",
each if [UnitPrice] >= 20 then "Premium"
else if [UnitPrice] >= 10 then "Standard"
else "Budget",
type text
)Combining Conditions
Use and, or, and not to combine logical expressions:
if [Region] = "East" and [Quantity] > 5 then "High-volume East"
else if [Region] = "West" or [Region] = "North" then "West/North"
else "Other"Operator precedence: not binds tightest, then and, then or. Use parentheses to make complex conditions clear:
if ([Region] = "East" or [Region] = "West") and [Quantity] > 5
then "High volume"
else "Standard"Null and Conditionals
Be careful with null values in conditions. A comparison involving null returns null, not false:
// If [Region] is null, this evaluates to null — not false
if [Region] = "East" then "East" else "Other"When the condition is null (neither true nor false), M raises an error. To guard against this:
if [Region] <> null and [Region] = "East" then "East" else "Other"Or test for null first:
if [Region] = null then "Unknown"
else if [Region] = "East" then "East"
else "Other"if as an Expression
Since if...then...else is an expression (not a statement), it returns a value and can be used anywhere a value is expected:
let
Multiplier = if includesTax then 1.08 else 1.0,
Total = [UnitPrice] * [Quantity] * Multiplier
in
TotalYou can nest if expressions inside function arguments, list items, or record fields.
Best Practices
- Always include
else. M requires it, and it forces you to think about the default case. - Guard against null in conditions where the tested column might contain null values.
- Use
List.Containsfor many-of checks instead of chaining multipleorconditions:
``powerquery if List.Contains({"East", "West", "North"}, [Region]) then "Domestic" else "International" ``
- Keep conditions readable by extracting complex logic into named steps:
``powerquery let IsHighValue = [UnitPrice] >= 20 and [Quantity] >= 10, Category = if IsHighValue then "Premium" else "Standard" in Category ``
- Prefer
Table.SelectRowsover adding a boolean column and then filtering — it is more direct and may fold to the data source.