What is the best practice in applying filters with CALCULATE() function in Power BI?
Using FILTER() as below:
Most Expensive Non-Organic = CALCULATE(MAX(dProduct[Amount]), FILTER(dProduct, dProduct[IsOrganic]="N"))
Or, Using a direct Boolean Expression as below:
Most Expensive Non-Organic = CALCULATE(MAX(dProduct[Amount]),'dProduct'[IsOrganic]="N")
When you write a CALCULATE statement, all the filter arguments are table expressions, such as a list of values for one or more columns, or for an entire table. For example, when you write:
CALCULATE (
<expression>,
table[column] = <value>
)
In reality the filter expression you wrote is transformed in:
CALCULATE (
<expression>,
FILTER (
ALL ( table[column] ),
table[column] = <value>
)
)
This behavior is identical for all the filter arguments of CALCULATE and CALCULATETABLE.
Your first statement is rather bad.
CALCULATE(MAX(dProduct[Amount]), FILTER(dProduct, dProduct[IsOrganic]="N"))
correct way for use filter in your example:
CALCULATE(MAX(dProduct[Amount]), FILTER(ALL(dProduct[IsOrganic]), dProduct[IsOrganic]="N"))
because you provide as filter a full EXPANDED table (you push many column from dProduct and related table).
Read this article:
https://www.sqlbi.com/articles/expanded-tables-in-dax/
Related
I want to count the occurrences of values in a column. In my case the value I want to count is TRUE().
Lets say my table is called Table and has two columns:
boolean value
TRUE() A
FALSE() B
TRUE() A
TRUE() B
All solutions I found so far are like this:
count_true = COUNTROWS(FILTER(Table, Table[boolean] = TRUE()))
The problem is that I still want the visual (card), that displays the measure, to consider the filters (coming from the slicers) to reduce the table. So if I have a slicer that is set to value = A, the card with the count_true measure should show 2 and not 3.
As far as I understand the FILTER function always overwrites the visuals filter context.
To further explain my intent: At an earlier point the TRUE/FALSE column had the values 1/0 and I could achieve my goal by just using the SUM function that does not specify a filter context and just acts within the visuals filter context.
I think the DAX you gave should work as long as it's a measure, not a calculated column. (Calculated columns cannot read filter context from the report.)
When evaluating the measure,
count_true = COUNTROWS ( FILTER ( Table, Table[boolean] = TRUE() ) )
the first argument inside FILTER is not necessarily the full table but that table already filtered by the local filter context (including report/page/visual filters along with slicer selections and local context from e.g. rows/column a matrix visual).
So if you select Value = "A" via slicer, then the table in FILTER is already filtered to only include "A" values.
I do not know for sure if this will fix your problem but it is more efficient dax in my opinion:
count_true = CALCULATE(COUNTROWS(Table), Table[boolean])
If you still have the issue after changing your measure to use this format, you may have an underlying issue with the model. There is also the function KEEPFILTERS that may apply here but I think using KEEPFILTERS is overcomplicating your case.
im' working with analysis services. I need to perform a calculation and for this i use kpi. In the field "value expression" from KPI i establishid the calculation with an expression MDX. Works fine but i don't know how put the clause "WHERE" in the query o how use it
(([Measures].[Recuento Factonlymatriculacion],[Dimmatriculacion].[Nivel].&[Universitario])*100)/([Measures].[Recuento Factsolicitud],[Dimplan].[Nivel].&[Universitario]))
WHERE
([Measures].[Recuento Factsolicitud],[Dimaniosolicitud].[Anio]) IS ([Measures].[Recuento Factmatriculacion],[Dimmatriculacion].[Anio])
I don't think you need WHERE. Just form a two part tuple, with Anio as the second part:
(
DIVIDE(
([Measures].[Recuento Factonlymatriculacion],[Dimmatriculacion].[Nivel].&[Universitario] * 100),
[Measures].[Recuento Factsolicitud],[Dimplan].[Nivel].&[Universitario]
)
, [Measures].[Recuento Factmatriculacion],[Dimmatriculacion].[Anio]
)
But there looks to be an issue as Anio is part of Measures so I don't understand how your original logic will return anything other than blank?
I have two facts tables, First and Second, and two dimension tables, dimTime and dimColour.
Fact table First looks like this:
and facet table Second looks like this:
Both dim-tables have 1:* relationships to both fact tables and the filtering is one-directional (from dim to fact), like this:
dimColour[Color] 1 -> * First[Colour]
dimColour[Color] 1 -> * Second[Colour]
dimTime[Time] 1 -> * First[Time]
dimTime[Time] 1 -> * Second[Time_]
Adding the following measure, I would expect the FILTER-functuion not to have any affect on the calculation, since Second does not filter First, right?
Test_Alone =
CALCULATE (
SUM ( First[Amount] );
First[Alone] = "Y";
FILTER(
'Second';
'Second'[Colour]="Red"
)
)
So this should evaluate to 7, since only two rows in First have [Alone] = "Y" with values 1 and 6 and that there is no direct relationship between First and Second. However, this evaluates to 6. If I remove the FILTER-function argument in the calculate, it evaluates to 7.
There are thre additional measures in the pbix-file attached which show the same type of behaviour.
How is filtering one fact table which has no direct relationship to a second fact table affecting the calculation done on the second table?
Ziped Power BI-file: PowerBIFileDownload
Evaluating the table reference 'Second' produces a table that includes the columns in both the Second table, as well as those in all the (transitive) parents of the Second table.
In this case, this is a table with all of the columns in dimColour, dimTime, Second.
You can't see this if you just run:
evaluate 'Second'
as when 'evaluate' returns the results to the user, these "Parent Table" (or "Related") columns are not included.
Even so, these columns are certainly present.
When a table is converted to a row context, these related columns become available via RELATED.
See the following queries:
evaluate FILTER('Second', ISBLANK(RELATED(dimColour[Color])))
evaluate 'Second' order by RELATED(dimTime[Hour])
Similarly, when arguments to CALCULATE are used to update the filter context, these hidden "Related" columns are not ignored; hence, they can end up filtering First, in your example. You can see this, by using a function that strips the related columns, such as INTERSECT:
Test_ActuallyAlone = CALCULATE (
SUM ( First[Amount] ),
First[Alone] = "Y",
//This filter now does nothing, as none of the columns in Second
//have an impact on 'SUM ( First[Amount] )'; and the related columns
//are removed by the INTERSECT.
FILTER(
INTERSECT('Second', 'Second')
'Second'[Colour]="Red"
)
)
(See these resources that describe the "Expanded Table"
(this is an alternative but equivalent explanation of this behaviour)
https://www.sqlbi.com/articles/expanded-tables-in-dax/
https://www.sqlbi.com/articles/context-transition-and-expanded-tables/
)
I am trying to calculate month over month difference but it makes data negative.
I created a measure, but it makes source data negative.
CALCULATE (
COUNTA ( SOURCE_DATA[COLUMN] ),
FILTER ( SOURCE_DATA, SOURCE_DATA[YYYYMM] = "201906" )
)
- (
CALCULATE (
COUNTA ( SOURCE_DATA[COLUMN] ),
FILTER ( SOURCE_DATA, SOURCE_DATA[YYYYMM] = "201905" )
)
)
The outcome is correct, but it changes data in previous month to negative.
This is due to the filter context and the way you've written the measure.
Look at the visual table. For the field corresponding to Column = 201905 and row = GA you get -16 813. This is because the context of the visual table tells CALCULATE to COUNTA(SOURCE_DATA[Column]) only when MtM = GA and Columns = 201905. However, adding the FILTER you also tell CALCULATE to keep these criteria AND also make sure that SOURCE_DATA[Column] = 201906 in the first calculate and 201905 in the second one.
This results in CALCULATE looking for rows where Column is both 201905 and 201906 at the same time. Or in other words you generate a venn diagram with no overlapping fields. Therefore the first calculate evaluates to 0 and the second to 16 813, so that the measure is actually evaluating 0-16813 = -16 813.
Since you didn't post any description of your data model I can inly guess what it looks like. However, since you're filtering on the SOURCE_DATA table I guess you don't use a Calendar table. This you should do! Have a calendar with a 1:* (1-to-many) relationship with the SOURCE_DATA and do filtering on the calendar. In addition you can have dynamically calculated day/week/month/year offsets so that you can create measures which don't have to be updated when there's a new month.
I think this video can be helpful: sqlbi videolecture
Also, have a look at this article: sqlbi filter in calculate
Use first two digits of Column to give a name to a new column.
I have a list of companies and their NAICS ID. I would like to filter these into a pie chart but I don't want the 90000 different names (just the general ex. Agriculture or Mining). I want to utilize the first two digits in for the column to identify its general name. I am trying to use the DAX expression Switch to get this started. Is there a filter to do this within PowerBI?
I haven't started yet since I am not sure if this is possible.
You could simply create a calculated column based off of the original NAICS code using the following:
FirstTwoDigitsOfNAICS :=
SWITCH (
TRUE (),
LEFT ( 'Table'[NAICSCode] ) = x, "Something",
LEFT ( 'Table'[NAICSCode] ) = y, "Something Else"
)
This DAX will simply pull the first two characters from the entire code.