Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.
Hi All,
Struggling to understand this behaviour of calculate. Newbie here. I have two tables. A sales table and a product table. I am creating a calculated column inside product table to to calculate sales of each product only when the quantity sold (in sales table) is greater than 1.
In the screenshot, you can see that Calculate doesn't do context transition when using a filter inside. However, if I write the formula as
single calculate = calculate(sum(pk_total sales amount), filter(all(sales[quantity), sales[quantity)>1). If yes, then context transition must not have been obeyed in the first place!
Hi @pankajk83
The reason is very simple. CACULATE imposes context transition over the first Argument (the expression). However, the 2nd argument (filter argument) of CALCULATE is evaluated in the outer filter context. But guess what! There is no outer filter context in this case. It's a calculated column with only row context.
When you wrap the whole formula with another CALCULATE then the inner calculate in its totality becomes the expression argument of the outer CALCULATE. Therefore, context transition is applied and hence "FILTER ( 'Table'..." becomes "FILTER ( CALCULATETABLE ( 'Table' )..."
Thank you. However, why does the same formula obey context transition when I use the ALL function
@pankajk83
Yes that is becuase ALL(Sales[Quantity]) removes the filter from only that column. I would also say that FILTER ( VALUES ( Sales[Quantity] ),... would also give the same result.
Accordingly, without the outer filter context FILTER ( Sales,... is equivalent to FILTER ( ALL ( Sales ),...
Apologies that I might be dragging this a little too far, but you see, using ALL, as you said, removes the filter from only that column. However, I am not doing this in a visual but in a calculated column. In thet case, there is no filter context at all when filter is first evaluated. So I am confused why does the presence of ALL make any difference.
@pankajk83
As I mentioned in my previous reply, there is absolutely no difference, in this case, between using FILTER - ALL or FILTER - VALUES. In fact VALUES, DISTINCT, ALLSECTED will all perform as ALL because the is no outer filter context.
What you are missing here is that the filter argument of CALCULATE replaces the filter context created by CALCULATE. When placed in a calculated column, CALCULATE converts all the columns of the current row of the table into a newly created filter context. When you use FILTER - Table you actually replace that filter context with a new one. Except this time the new filter context includes all the rows, not only the current row. That is the very same effect of FILTER - ALL ( Table ).
When you use FILTER - ALL ( Table[Column] ) you only replace that column in the filter context created by CALCULATE but the rest of that filter remains.
My recommendation, avoid using CALCULATE in creating calculated columns but rather try to rely on a NoCALCULATE approach.
@pankajk83
Before reading my answer, I would suggest you to go through these two blogs
https://www.sqlbi.com/articles/expanded-tables-in-dax/
https://xxlbi.com/blog/power-bi-antipatterns-9/
https://xxlbi.com/blog/power-bi-antipatterns-10/
I would like to answer your question in two parts, first lets see the difference between, filter function in calculate and predicate filter in calculate.
-- filter predicate in calculate
single calculate=calculate(sum(Sales[pk_total sales amount]),Sales[Quantity]>1)
when you are filtering on a column within calculate as filter predicate that means you are filtering on the expanded table (which includes columns from sales and product).
The equivalent of above DAX expression is:
single calculate=calculate(sum(Sales[pk_total sales amount]), Filter(all(Sales),Sales[Quantity]>1) )
However, with the below syntax you are filtering on sales table only.
single calculate=calculate(sum(Sales[pk_total sales amount]), Filter(Sales,Sales[Quantity]>1) )
Now coming to the next part, first of all
One of the rule for calculate function is, calculate fitler arguments are evaluated in original row and filter context (i.e row context in your scenario) and the result of these arguments then effect the filters created due to context transition.
with filter predicate (Sales[Quantity] > 1) or (Filter(all(sales), sales[quantity] >1):
with double calculate with filter function:
with Filter(Sales, Sales[Quantity] > 1)
Note: I am not an expert in the core concepts of DAX. I wrote the above answer based on my understanding, so take it with a grain of salt.
If the post helps please give a thumbs up
If it solves your issue, please accept it as the solution to help the other members find it more quickly.
Tharun
correct me if I'm wrong but guessing:
Are you using CALCULATE() to make a calculated column? If that is the case that might be causing you trouble. Let me explain more about the logic:
single calculate makes the SUM() over the table, because there is no context transition at all. the measure would be working fine in a matrix if it's calculated in a measure, not in a column.
I don't know why the other two are working fine, but my theory is that ALL() is forcing to make the calculate in every different row.
It would be very useful to us you share the pbix file or your data to run some tests.
Hope been useful.
PD: sorry about my English still learning.
User | Count |
---|---|
50 | |
23 | |
18 | |
18 | |
13 |
User | Count |
---|---|
91 | |
86 | |
46 | |
28 | |
21 |