DAX (Data Analysis Expressions) is the formula language behind Power BI's brain. It allows you to create custom calculations, aggregations, and filters beyond the built-in visual options — making your reports smarter and more interactive.
Quick Answer
DAX (Data Analysis Expressions) is Power BI's formula language for creating measures and calculated columns. The most important function is CALCULATE — it evaluates any expression in a modified filter context, enabling percentage of totals, year-over-year comparisons, and dynamic segmentation.
💬 Real-World Analogy — Excel on Steroids
If you've used Excel formulas like SUMIF() or
VLOOKUP(), you already understand the idea behind DAX. But DAX
goes significantly further:
- Work on a single sheet or range
- Calculated at the cell level
- Static — don't respond to slicers
- No cross-table awareness
- Work across multiple related tables
- Recalculate dynamically per visual context
- Respond instantly to slicers and filters
- Understand model relationships automatically
🧮 The Three Types of DAX Expressions
DAX can produce three fundamentally different outputs. Choosing the right one is the first skill to master:
- Stored permanently in the data model
- Calculated row-by-row at refresh time (Row Context)
- Increases model size — use sparingly
- Good for: categorisation, bucketing, combining fields
Profit = Sales[Total] - Sales[Cost]
- Calculated on the fly when a visual renders
- Responds dynamically to filters, slicers, and visual context (Filter Context)
- Memory-efficient — not stored in the model
- Good for: aggregations, KPIs, % of total, YTD
Total Sales = SUM(Sales[Amount])
- Returns a full table instead of a value or column
- Stored in the model like a regular table
- Used for Date tables, bridge tables, virtual aggregations
- Good for: advanced modelling, helper tables
HighValueOrders = FILTER(Sales, Sales[Amount] > 1000)
"Measures are like answering a question on demand. Calculated Columns are like writing the answer down ahead of time."
🔁 Filter Context vs Row Context
This is the concept that trips up most beginners — and unlocks everything once understood.
Used by Calculated Columns. Power BI evaluates the formula once for each row in the table — like Excel dragging a formula down.
Margin % = DIVIDE(Sales[Profit], Sales[Total])
This runs for every row individually — each row knows its own Sales[Profit] and Sales[Total].
Used by Measures. The filter context is the set of filters currently applied by visuals, slicers, and report-level filters.
Total Sales = SUM(Sales[Amount])
When a slicer selects "North Region", this measure automatically sums only North Region sales.
🔥 Most Used DAX Functions
These are the functions you will use in almost every Power BI project:
SUM() / AVERAGE() / COUNT()CALCULATE()DIVIDE()FILTER()IF() / SWITCH()RELATED()SUMX() / AVERAGEX()TOTALYTD() / SAMEPERIODLASTYEAR()⚙️ Practical DAX Examples
Here are three measures you should build in every sales report:
Total Sales = SUM(Sales[Amount])
% of Total =
DIVIDE(
SUM(Sales[Amount]),
CALCULATE(SUM(Sales[Amount]), ALL(Sales))
)
Sales YTD =
TOTALYTD(SUM(Sales[Amount]), Dates[Date])
⚠️ Golden Rules for Writing DAX
- Use measures over calculated columns — measures are more efficient, flexible, and respond to filter context. Use calculated columns only when you need to store a value per row.
- Use DIVIDE() not the / operator — DIVIDE(a, b) returns BLANK instead of an error when b is zero, keeping your visuals clean.
- Name measures clearly — "Total Sales ₹" is better than "Measure1". Clear names make reports self-documenting.
- Format your DAX — write one argument per line for complex formulas. Use daxformatter.com to auto-format.
- Test incrementally — build complex DAX one function at a time, verifying the result at each stage before adding more complexity.
- Master CALCULATE() early — it is the gateway to advanced DAX. Every YTD, comparison, and overriding filter measure uses it.
🧠 Try It Yourself — Three Starter Measures
Build these three measures in your Sales dataset to practise DAX:
-
Total Sales using SUM()
Add this to a Card visual. Apply a Region slicer and confirm it updates dynamically.Total Sales = SUM(Sales[Amount]) -
Profit Calculated Column
In the Sales table, create a new column:Notice it runs row-by-row and appears as a new column in the table.Profit = Sales[Amount] - Sales[Cost] -
% of Total Sales using DIVIDE()
Add this to a table visual alongside Product Name. Confirm each row shows that product's share of total sales as a percentage.% of Total = DIVIDE( SUM(Sales[Amount]), CALCULATE(SUM(Sales[Amount]), ALL(Sales)), 0 )