Lesson 6 of 16 · Level 2: Intermediate
DAX for Beginners: Measures and Calculated Columns
- ⏱ 12 min read
- ❓ 4 review questions
- ✍️ Exercise with solution
In this lesson
- What DAX is and the difference between calculated columns and measures.
- How to write measures with SUM, AVERAGE, COUNTROWS, DISTINCTCOUNT and DIVIDE.
- How SUMX calculates row by row.
- What filter context is and why one measure returns a different result in every cell.
- How to build the base measures on Summit's real data and check the results.
DAX (Data Analysis Expressions) is the formula language of Power BI, Power Pivot and other Microsoft tools. It looks like Excel formulas, with one fundamental difference: it doesn't work cell by cell but with tables and columns, and it recalculates based on whatever filters the user has applied. Mastering measures is what turns a pretty report into an analytical one.
Calculated columns vs. measures
- What it is
- A new column in a table, calculated row by row.
- When it's calculated
- On data refresh; stored in the model.
- Uses memory
- Yes.
- Use it to
- Classify or group rows (segments, bands) when you need the value on an axis or in a slicer.
- Example
- Order size = "Large" if Amount ≥ 1,000.
- What it is
- A calculation evaluated on the fly, based on the filters.
- When it's calculated
- Every time a visual shows it.
- Uses memory
- No.
- Use it for
- Totals, averages, percentages, comparisons: any number that gets aggregated.
- Example
- Total Sales, Gross Margin %, Avg Order Value.
Rule of thumb: if the result is a number that will be aggregated, it's a measure. Calculated columns are for when you need a label on each row. And if you can create the column in Power Query, do it there instead.
Your first measure
In Report view, select the Sales table in the Data pane and click New measure. Type in the formula bar:
Total Sales = SUM ( Sales[Amount] )
- The measure's name goes to the left of the equals sign.
- Columns are written as
Table[Column]. - DAX function names are always in English (SUM, AVERAGE, CALCULATE), whatever the interface language.
- This course uses commas between arguments, the default for U.S. English settings.
The measure appears with a calculator icon. Drag it into a card, a chart by city or a matrix by month: in each place it calculates for exactly what that spot represents.
Create an empty table to hold measures (Home › Enter data, name it "_Measures" and load a one-column table you'll hide later). Move your measures there with Measure tools › Home table. When you have 40 measures, you'll be glad you did.
Basic functions
We'll use this small sample Sales table (Amount = Quantity × Price):
| Customer | Product | Quantity | Price | Unit cost |
|---|---|---|---|---|
| C1 | Rice | 10 | $4.50 | $3.20 |
| C2 | Oil | 5 | $9.00 | $6.50 |
| C1 | Oil | 8 | $9.00 | $6.50 |
| C3 | Rice | 20 | $4.50 | $3.20 |
| C2 | Sugar | 12 | $3.80 | $2.90 |
| C1 | Rice | 6 | $4.50 | $3.20 |
| Measure | Formula | Result for the table |
|---|---|---|
| Units | SUM ( Sales[Quantity] ) | 61 |
| Orders | COUNTROWS ( Sales ) | 6 |
| Customers | DISTINCTCOUNT ( Sales[Customer] ) | 3 |
| Highest Price | MAX ( Sales[Price] ) | $9.00 |
| Avg Quantity | AVERAGE ( Sales[Quantity] ) | 10.17 |
SUMX: calculate row by row, then add up
If the table has no Amount column, only Quantity and Price, you can't write SUM(Quantity) * SUM(Price): you'd multiply the totals (61 × 35.30), which is meaningless. You need to multiply on every row and then add. That's what iterator functions, the ones ending in X, are for:
Total Sales =
SUMX ( Sales, Sales[Quantity] * Sales[Price] )
Total Cost =
SUMX ( Sales, Sales[Quantity] * Sales[Unit cost] )
SUMX walks through the Sales table, evaluates the expression on each row (45, 45, 72, 90, 45.60, 27) and adds them up: $324.60. Total cost is $234.50. AVERAGEX, MINX, MAXX and COUNTX work the same way.
1. Your table has Quantity and Price but no Amount. Which measure calculates sales correctly?
SUMX multiplies on each row and then adds the results. Multiplying the totals gives a meaningless number.
Measures built on other measures
Once the base measures exist, build the rest on top of them. It's easier to read, and if the definition of sales changes, everything updates:
Gross Profit = [Total Sales] - [Total Cost]
Gross Margin % = DIVIDE ( [Gross Profit], [Total Sales] )
Avg Order Value = DIVIDE ( [Total Sales], [Orders] )
With the sample table: Gross Profit = 324.60 − 234.50 = $90.10; Gross Margin % = 90.10 ÷ 324.60 = 27.8%; Avg Order Value = 324.60 ÷ 6 = $54.10.
Always use DIVIDE instead of the / operator: if the denominator is zero or blank, DIVIDE returns a blank (or whatever you pass as the third argument) instead of an error.
Format each measure under Measure tools: Gross Margin % as a percentage with one decimal, sales as currency, and so on. The format travels with the measure to every visual.
The base measures on Summit's data
Summit's Sales table has no Amount or Cost column. It has Quantity and UnitPrice, and each product's cost lives in the Products dimension. That's typical of real systems, and here's how you handle it:
Total Sales =
SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )
Total Cost =
SUMX ( Sales, Sales[Quantity] * RELATED ( Products[UnitCost] ) )
Orders = DISTINCTCOUNT ( Sales[OrderID] )
Lines = COUNTROWS ( Sales )
- RELATED fetches, for the row SUMX is currently on, a value from the table on the "one" side of the relationship (Products). It works because you created the relationship in Lesson 5; without it you get an error.
- Orders uses DISTINCTCOUNT because each order spans several rows, one per product. COUNTROWS counts lines, not orders.
Check your measures against these results for the full period (2025–2026, no filters):
| Measure | Result | How it's calculated |
|---|---|---|
| Total Sales | $515,969.03 | Sum of Quantity × UnitPrice over 4,430 rows |
| Total Cost | $365,128.73 | Sum of Quantity × the product's UnitCost |
| Gross Profit | $150,840.30 | 515,969.03 − 365,128.73 |
| Gross Margin % | 29.2% | 150,840.30 ÷ 515,969.03 |
| Orders / Lines | 2,205 / 4,430 | DISTINCTCOUNT vs. COUNTROWS |
| Avg Order Value | $234.00 | 515,969.03 ÷ 2,205 |
| Units / Avg Unit Price | 75,923 / $6.80 | 515,969.03 ÷ 75,923 |
Put them in a matrix by Category and the first business insight appears: the category that sells the least earns the best margin.
Beverages sells $152,775 (29.6% of the total) but keeps 32 cents of every dollar. The "(Blank)" row for the P99 sales shows a 100% margin because they have no cost: one more reason to fix them.
Filter context: the most important idea in DAX
Put the Total Sales measure in a matrix with Product on rows:
| Product | Total Sales | Gross Margin % |
|---|---|---|
| Rice | $162.00 | 28.9% |
| Oil | $117.00 | 27.8% |
| Sugar | $45.60 | 23.7% |
| Total | $324.60 | 27.8% |
It's one formula, yet every row returns something different. Why? Because before calculating, Power BI applies that cell's filter context: on the "Rice" row, the Sales table is filtered to rice rows and SUMX walks only those. The Total row has no product filter, so it walks them all. Filter context comes from the visual's rows and columns, slicers, page and report filters, and cross-filtering from other visuals.
The total Gross Margin % (27.8%) isn't the sum or the simple average of the rows: it's recalculated from total profit and total sales. That's correct. It's why percentages and averages must always be measures, never columns that get added up.
2. Why does the same Total Sales measure show $162 on the Rice row and $324.60 on the total?
Filter context is the foundation of DAX: a measure is evaluated after each cell's filters are applied.
Implicit vs. explicit measures
When you drag a numeric column into a chart, Power BI creates an implicit measure (for example, "Sum of Amount"). It works to get started, but you can't reuse it in other formulas or control its format in one place, and some advanced features don't support it. The professional practice is to create explicit measures for everything you display.
3. Which of these should be a measure rather than a calculated column?
Percentages must recalculate in every context; as a column, the total would be wrong.
4. At Summit, Avg Order Value = DIVIDE ( [Total Sales], COUNTROWS ( Sales ) ) returns $116.47. What's wrong?
515,969.03 ÷ 4,430 = 116.47 is average sales per line; 515,969.03 ÷ 2,205 = 234.00 is average sales per order. Before you count, define what a row is.
Common beginner DAX mistakes
Creating a "Margin %" calculated column and summing it in totals.
Percentages and averages are measures: they recalculate from each context's totals.
Multiplying totals: SUM(Quantity) * SUM(Price).
SUMX multiplies on each row and then adds.
Counting orders with COUNTROWS on a table of order lines.
DISTINCTCOUNT on the order number.
Dividing with / and filling the report with errors or infinity.
DIVIDE, which returns a blank when the denominator is zero.
Repeating the sales logic inside every new measure.
Reuse measures: Gross Profit = [Total Sales] - [Total Cost].
Practice exercise: your base measures
Using the Lesson 5 model, create these in a measures table:
- Total Sales, Total Cost, Gross Profit and Gross Margin %.
- Orders, Customers (distinct) and Avg Order Value.
- Units and Avg Unit Price (sales ÷ units).
- Put them in a matrix by Category and by Region, and confirm the total Gross Margin % recalculates.
See solution
Total Sales = SUMX ( Sales, Sales[Quantity] * Sales[UnitPrice] )
Total Cost = SUMX ( Sales, Sales[Quantity] * RELATED ( Products[UnitCost] ) )
Gross Profit = [Total Sales] - [Total Cost]
Gross Margin % = DIVIDE ( [Gross Profit], [Total Sales] )
Orders = DISTINCTCOUNT ( Sales[OrderID] )
Customers = DISTINCTCOUNT ( Sales[CustomerID] )
Avg Order Value = DIVIDE ( [Total Sales], [Orders] )
Units = SUM ( Sales[Quantity] )
Avg Unit Price = DIVIDE ( [Total Sales], [Units] )
These formulas fit Summit's file, where each Sales row is an order line. If you add an Amount column in Power Query (as Lesson 12 suggests), Total Sales can simply be SUM ( Sales[Amount] ); and if each row in your table were a whole order, Orders would be COUNTROWS ( Sales ). By region you should see Midwest $133,438.18, West $131,911.93, South $130,216.94 and Northeast $120,401.98.
Summary
- DAX works with tables and columns; function names are always in English.
- Measures for numbers that get aggregated; calculated columns only to classify rows.
- SUM, AVERAGE, COUNTROWS, DISTINCTCOUNT and DIVIDE cover the basics; SUMX calculates row by row.
- Build measures from other measures and format them once.
- Filter context gives every cell its own result.
- RELATED brings dimension values into SUMX; DISTINCTCOUNT counts orders, not lines.
Next lesson: CALCULATE and Filter Context in DAX. You'll learn CALCULATE, the most important function in DAX, which lets you change the filter context.
Create your account in 30 seconds, mark your lessons and download your certificate at the end.