🚀 New batches open: Advanced Excel • Power BI • SQL • AI for Analytics — Book a free demo
Home / Power BI Tutorial / DAX reference

DAX quick reference

The sheet to keep open while you build a report. Every formula on it runs right here, against a real model.

DAI ACADEMY — DAX quick reference Every formula on this page runs. Press Run on any box to see the answer against the model below, then change it and run it again.

How to use this

This is the sheet to keep open while you build a report. It is organised the way you actually reach for things — add something up, then split it, then compare it with last year — rather than alphabetically.

Everything here is written against the same small model, so you can try any formula immediately without inventing data. Nothing on this page is theory. If a formula is printed here, it has been run.

The one sentence that matters A measure has no value of its own. It is a recipe, and it produces a different number in every cell of your report depending on what is filtering that cell. Almost every DAX question that starts “why is this number wrong” is really a question about filter context.

The model

One fact table and three dimensions — the shape most real Power BI models take.

48 sales rows across 2024 and 2025. Product holds six products in two categories, Region four regions with a manager each, and Calendar one row per day across both years.

Get the data and build it yourself

Reading DAX and writing DAX are different skills. Download the model, load it into Power BI Desktop, and type the formulas below into your own report — you should get exactly the numbers this page shows, because it is exactly the same data.

Loading it into Power BI Desktop

  1. Home → Get data → Excel workbook, pick the file, and tick all four sheets: Sales, Product, Region, Calendar. Click Load.
  2. Open Model view (the third icon down the left edge). Power BI will have guessed some relationships. Delete whatever it guessed — you want to build them yourself, and its guesses are often wrong.
  3. Drag Product[ProductID] onto Sales[ProductID]. Do the same for Region[RegionID] and for Calendar[Date] onto Sales[Date]. Each one should come out one-to-many, with the arrow pointing from the dimension towards Sales.
  4. Click the Calendar table, then Table tools → Mark as date table, and choose the Date column. Time intelligence will not work properly until you do this.
If the CSVs give you text instead of dates Power BI reads CSV dates using your Windows locale, and a date written 2025-03-06 can be read as text on an Indian regional setting. In Power Query, click the ABC icon on the Date column and choose Using locale → Date → English (United States). The .xlsx does not have this problem — the dates are already real dates in the file — which is why it is the one to prefer.

Check you loaded it correctly

Before writing anything clever, write these three and compare. If any of them disagrees, the load went wrong, not the formula.

MeasureYou should get
Total sales = SUM(Sales[Amount])30,37,800
Number of orders = COUNTROWS(Sales)48
Days = COUNTROWS(Calendar)731
Why 731 and not 730 2024 is a leap year. A date table has to cover every single day in the range with no gaps — that is what lets DATEADD, SAMEPERIODLASTYEAR and the rest do their job. A missing day is the most common reason time intelligence silently returns blank.

1. Adding things up

These take a whole column and collapse it to one number. They are the ones you will type most.

FunctionGives you
SUM(table[col])The total
AVERAGE(table[col])The mean, ignoring blanks
MIN / MAX(table[col])Smallest and largest
COUNT(table[col])How many rows have a value there
COUNTROWS(table)How many rows, full stop
DISTINCTCOUNT(table[col])How many different values
COUNT or COUNTROWS? COUNTROWS(Sales) counts rows. COUNT(Sales[Amount]) counts rows where Amount is not blank. On clean data they agree; on real data they do not, and the gap is usually the thing you wanted to know about.

2. Splitting it up

The same measure gives a different answer in every row of a visual. Nothing about the formula changes — the report supplies a different set of rows to each line.

Change Region[Region] in your head to Product[Category] and the same three measures answer a completely different question. That is the whole idea of a measure.

3. The X functions

An iterator goes down a table row by row, works something out on each row, and then aggregates the results. You need one whenever the calculation has to happen per row before it is totalled.

SUMX( table , expression evaluated on each row )
FunctionDoes
SUMXAdds up the per-row results
AVERAGEXAverages them
MINX / MAXXSmallest and largest of them
COUNTXCounts the non-blank results
The mistake that quietly gives a wrong answer Suppose price varies per row. SUM(Sales[Qty]) * SUM(Sales[Price]) multiplies two grand totals and produces a number that means nothing. SUMX(Sales, Sales[Qty] * Sales[Price]) multiplies within each row and then adds up, which is what you meant.
It looks right, it returns a number, and nobody notices until a client checks it. When a calculation has a times or a divided by in it, ask whether it has to happen per row.

4. CALCULATE — the one that changes everything

CALCULATE evaluates an expression with the filters you give it. It is the most powerful function in DAX and the one that causes the most confusion, because of a single rule.

CALCULATE( expression , filter , filter , ... )
The rule A filter argument does not narrow what is already there. It replaces the filter on the columns it mentions, and leaves everything else alone. That is why the next example gives South’s number on every single row.

Forced South mentions Region, so it throws away the row’s own region and uses South instead — the same number all the way down. Computers here mentions Category, not Region, so each row keeps its own region and gets computers only. Read those two columns until the difference is obvious; it is the single most useful thing on this page.

Removing filters

ALL(Region) ignores whatever the row is filtering on that table, which is how you get a grand total to divide by. That pattern — a measure over the same measure with ALL — is how every percentage-of-total in Power BI is built.

More complicated conditions

A plain column = value filter cannot express “bigger than”. For that, filter a table with FILTER.

FunctionUse it to
ALL(table)Ignore filters on that table entirely
FILTER(table, condition)Build a filtered table for CALCULATE
VALUES(table[col])The distinct values visible right now
DISTINCT(table[col])The distinct values, blanks aside

5. Decisions

FunctionDoes
IF(test, yes, no)One decision
SWITCH(TRUE(), test, result, ...)Several, in order — far more readable than nested IFs
AND / OR / NOTCombine conditions
ISBLANK(x)True when there is nothing there
BLANK()Return nothing on purpose, so the row disappears from a visual
Always DIVIDE, never the slash DIVIDE(a, b) returns blank when b is zero. a / b throws an error that breaks the whole visual, not just that one cell. There is no situation where the slash is the better choice.
DIVIDE(a, b, 0) if you want a zero instead of a blank.

6. Comparing with last year

Time intelligence needs a proper date table — one row per day, no gaps, marked as the date table in the model. Without one these functions return wrong answers rather than errors, which is worse.

FunctionGives you
TOTALYTD(expr, dates)Running total from 1 January
SAMEPERIODLASTYEAR(dates)The matching period a year back
PREVIOUSYEAR(dates)The whole of last year
DATEADD(dates, n, unit)Shift by any amount — the flexible one
YEAR / MONTH / DAY(date)Pull a part out of a date
Why 2024 has no growth figure There is no 2023 in the model, so last year is blank and the growth calculation has nothing to divide by. That is correct behaviour, not a bug — and it is exactly what your own report will do in its first year. Decide now whether a blank or a dash is what your client should see.

7. Reaching across a relationship

In a calculated column on the fact table, RELATED fetches a value from the dimension on the one side of the relationship.

Usually you do not need it If the relationship exists, a measure can already filter by Product[Category] without RELATED — the model does the work. RELATED is for calculated columns, where you are physically building a value into each row.

8. Tidying the number

FORMAT turns a number into text Once formatted it cannot be summed, sorted numerically or plotted. Use it for a label or a card, never for something a visual has to do arithmetic on. To make a number look right while staying a number, set the format on the measure instead.

9. The traps that cost hours

SymptomWhat is actually wrong
The total is not the sum of the rowsCorrect, and usually right. A measure is recalculated for the total row against all the data, not added up from the rows above.
Every row shows the same numberA CALCULATE filter is replacing the filter the row was supplying.
Multiplication comes out far too highTwo grand totals multiplied. You needed SUMX.
The whole visual errorsA division by zero. Use DIVIDE.
Time intelligence returns silly numbersNo proper date table, or it is not marked as one.
A measure will not sortFORMAT turned it into text.
Blank rows appear in a visualRows in the fact table with no match in the dimension.

10. Measure or calculated column?

MeasureCalculated column
Worked outWhen the visual asksOnce, at refresh
Stored in the fileNoYes — it makes the file bigger
Responds to slicersYesNo
Use it forAnything you aggregate: totals, ratios, countsSomething you slice or group by

When in doubt, write a measure. A calculated column that should have been a measure bloats the model and stops responding to filters. The reverse mistake is far less costly.

Keep going This page is the summary. The reasoning behind it is in the free 12-day Power BI course — every day has runnable examples and the mistakes explained rather than just listed.