DAX Fundamentals
Write your first DAX measures β SUM, AVERAGE, COUNT, DISTINCTCOUNT, and basic statistical functions. Learn the VAR/RETURN pattern and understand row context vs filter context.
Your first DAX measures
Think of a spreadsheet formula. In Excel, you type =SUM(B2:B100) to add up a column. DAX works the same way β but instead of cell ranges, you reference column names: SUM(Sales[Revenue]).
The magic of DAX is filter context. If a slicer is set to βNorth Regionβ, SUM(Sales[Revenue]) automatically sums only North Region revenue. You write the formula once, and it adapts to whatever the user filters.
This module covers the essential aggregation functions and introduces the VAR/RETURN pattern that makes complex measures readable.
Essential aggregation functions
| Function | What It Does | Example |
|---|---|---|
SUM(column) | Adds all values in a column | Total Revenue = SUM(Sales[Revenue]) |
AVERAGE(column) | Calculates the mean | Avg Order Value = AVERAGE(Sales[OrderTotal]) |
COUNT(column) | Counts non-blank values | Order Count = COUNT(Sales[OrderID]) |
COUNTROWS(table) | Counts rows in a table | Transaction Count = COUNTROWS(Sales) |
DISTINCTCOUNT(column) | Counts unique values | Unique Customers = DISTINCTCOUNT(Sales[CustomerID]) |
MIN(column) | Finds the smallest value | First Sale = MIN(Sales[OrderDate]) |
MAX(column) | Finds the largest value | Latest Sale = MAX(Sales[OrderDate]) |
Riley at Coastal Fresh (π) creates her first set of measures:
Total Revenue = SUM(Sales[Revenue])
Total Cost = SUM(Sales[Cost])
Profit = [Total Revenue] - [Total Cost]
Profit Margin = DIVIDE([Profit], [Total Revenue])
Notice how Profit references other measures β DAX measures can build on each other. And DIVIDE handles division by zero gracefully (returns BLANK instead of an error).
Exam tip: DIVIDE vs division operator
Always use DIVIDE(numerator, denominator) instead of numerator / denominator.
100 / 0β ErrorDIVIDE(100, 0)β BLANK (safe)DIVIDE(100, 0, 0)β 0 (custom fallback)
The exam tests this. Any measure that divides should use DIVIDE.
Statistical functions
| Function | What It Does |
|---|---|
MEDIAN(column) | Middle value when sorted |
STDEV.P(column) | Standard deviation (population) |
STDEV.S(column) | Standard deviation (sample) |
PERCENTILE.INC(column, percentile) | Value at a given percentile |
RANKX(table, expression) | Ranks rows by an expression |
Nadia at Prism Agency (π) uses statistical measures for campaign analysis:
Median CPC = MEDIAN(Campaigns[CostPerClick])
Top 10% Threshold = PERCENTILE.INC(Campaigns[Revenue], 0.9)
Variables: the VAR/RETURN pattern
Variables make complex DAX readable and efficient. Define values with VAR, return the result with RETURN.
Profit Margin % =
VAR TotalRevenue = SUM(Sales[Revenue])
VAR TotalCost = SUM(Sales[Cost])
VAR Profit = TotalRevenue - TotalCost
RETURN
DIVIDE(Profit, TotalRevenue)
Why variables matter:
- Readability: Each step has a clear name
- Performance: A variable is calculated once, even if referenced multiple times
- Debugging: You can change
RETURNto return any variable to check intermediate values
Kenji at Apex Manufacturing (π) writes a production efficiency measure:
Production Efficiency =
VAR ActualOutput = SUM(Production[UnitsProduced])
VAR PlannedOutput = SUM(Production[TargetUnits])
VAR Efficiency = DIVIDE(ActualOutput, PlannedOutput)
RETURN
Efficiency
Best practice: always use variables for multi-step measures
Even for simple two-step calculations, variables improve readability. Compare:
Without variables:
Margin = DIVIDE(SUM(Sales[Revenue]) - SUM(Sales[Cost]), SUM(Sales[Revenue]))With variables:
Margin =
VAR Rev = SUM(Sales[Revenue])
VAR Cost = SUM(Sales[Cost])
RETURN DIVIDE(Rev - Cost, Rev)The second version is easier to read, debug, and modify. It also performs better because SUM(Sales[Revenue]) is only calculated once.
Understanding filter context
The same measure returns different values depending on the filter context:
| Visual Context | Total Revenue Result |
|---|---|
| No filters | Sum of ALL revenue |
| Slicer: Region = βNorthβ | Sum of North region revenue only |
| Matrix row: Product = βAvocadoβ | Sum of Avocado revenue only |
| Both: North + Avocado | Sum of Avocado revenue in North region |
Dr. Ethan at Bayview Medical (π₯) creates Total Appointments = COUNTROWS(Appointments). When a doctorβs name is on the slicer, it shows that doctorβs appointments. When a department is selected, it shows that departmentβs count. Same measure β different context.
This is why measures are powerful: you write once, and the filter context handles the rest.
Knowledge check
Riley creates `Total Revenue = SUM(Sales[Revenue])`. She places it in a matrix visual with Regions as rows. North shows $50K, South shows $30K, but the total shows $120K (which is correct β there are also East and West). What's happening?
What does `DIVIDE(100, 0)` return in DAX?
π¬ Video coming soon
Next up: CALCULATE and Filter Context β the most powerful (and most tested) DAX function.