PowerBI 2 Handout
PowerBI 2 Handout
Last night we looked at some DAX expressions, using a training data set of sales for a
fictional company, provided by Microsoft. Here are the DAX expressions I walked through. I put
the measures in italics. The rest are calculated columns.
2. GrossMargin = Sales[SalesQuantity]*(Sales[UnitPrice]-Sales[UnitCost])
Calculate Gross Margin % as a measure. You do not need to specify a table when creating a
measure. Remember- any time you are dividing, or computing a ratio you probably want a
measure. They are tricky because you need to work out the evaluation context, but they are
much more flexible than calculated columns.
3. GrossMarginPct = sum(Sales[GrossMargin])/sum(Sales[SalesAmt])
Recalculate SalesAmt as a measure. We will use it later, so remember what you call it. Create
a table to hold all your measures (I called mine MyMeasures) or you will have trouble finding
them as your model gets bigger.
One of the great things about DAX is that not all your data needs to be on the same table.
Here, we calculate total sales as a measure with the quantity coming from the Sales table and
price coming from the Product table. If the relationship is many-to-one, use RELATED. If it is
one-to-many, use RELATEDTABLE (see below).
To count the number of sales for any product, create a calculated column on the Product table
and use the DAX function COUNTROWS on the RELATEDTABLE Sales.
6. NumberofSales = countrows(Relatedtable(Sales))
This example calculated the dollar value of sales for each product. This is a calculated
column on the Product table. For each product on the product table, DAX adds up the value of
an expression. Remember the difference between SUM and SUMX is that SUM adds up a column, and
SUMX adds up the result of a calculation. In this case the calculation is quantity x price,
and they are on the Sales table, so we need to use RELATEDTABLE.
7. SalesofProduct = sumx(RELATEDTABLE(Sales),Sales[SalesQuantity]*Sales[UnitPrice])
In this example, I showed a more complex DAX formula that ranks products based on their price.
The formula is a calculated column on the Product table. For each price, DAX counts the number
of rows where the current price is greater than the price being examined. Therefore, if the
row has the highest price, the program counts the number of rows with a higher price- there
are no prices higher than the highest price so it returns zero. When the formula examines the
2nd highest price it finds only one price that is higher so it returns a 1. It does this for
the entire Product table. There are several DAX functions in this expression and you might
want to look up exactly what they do. Microsoft has a great resource online. Just go to
https://dax.guide/ and you can find the syntax and explanation for all of the functions we
used- and hundreds more!
8. RankonPrice = countrows(
Filter(ALL('Product'[UnitPrice]),
'Product'[UnitPrice]>EARLIER('Product'[UnitPrice])
)
)+1
The CALCULATE function ignores any context except for what you add in the expression. Here we
calculated a measure for total sales of economy products. (Notice that we are using a
[TotalSales] measure we created earlier. If you didn’t do #4 and/or #5, this step won’t work.)
9. EconomySales = Calculate([TotalSales],'Product'[ClassName]="Economy")
FILTER is a Table function that filters out any rows that don’t meet a constraint. In this
case, if the class is not “Economy”, the CALCULATE function doesn’t happen. If you popped your
measure from #9 on to a report, you’ll see that it looked wrong. This DAX expression will make
your visualization make more sense.
DATEADD is part of the Time Intelligence family of DAX. It moves the entire column of data
forward or backward. In this expression, we move sales back one quarter. (Make sure to move
your measures to your Measures table!)
Subtract Sales this year from last year’s sales so we can do some year-over-year analysis.
Save it as a measure.
This measure calculates the difference in sales as a percentage. It allows me to show the
DIVIDE function in DAX. This function allows the code to run even if division by zero occurs.
Adjust the code to create a measure for cumulative sales last year.
Create a measure of cumulative sales difference. This is a great technique for tracking
performance against a target over time.
This is the code to create moving averages. This is the 30 day moving average. If you want 90
day MA, just change -30 to -90. This is very useful code for stock trading analysis.
In closing, just remember that when you write DAX, the syntax for calculated columns is always
‘Table’[Column] but for measures, you omit the table reference. Looking at our code, we write
‘Sales’[SalesAmt] because it is a calculated column on the Sales table. [TotalSales] is a
measure, because it does not depend on a table in the model. You don’t need to use this
syntax, but if you don’t it this way, it will be impossible to distinguish calculated columns
from measures in the DAX expression and as we saw, they act very differently!