Performance Problems with DAX expression - powerbi

I'm having a huge problem with performance in the below DAX measure.
Amount = CALCULATE (
SUMX (
'Financial All Scenarios',
IF (
SELECTEDVALUE ( 'Report Options'[Currency], "CD" ) = "USD",
'Financial All Scenarios'[GLAmountUSD],
IF (SELECTEDVALUE ( 'Report Options'[Currency], "CD" ) = "CD",
'Financial All Scenarios'[GLAmountCD],
'Financial All Scenarios'[GlAmountDoc]
)
)
)
)
This DAX measure does has the following. There is a disconnected filter table called Report Options, which has 3 a field called Currency with 3 values in it CD, USD, and DOC. This slicer is used to control which field is summed up from the fact table Financial All Scenarios. If nothing is selected from the Report Options table it defaults to CD.
I have a report that has a bunch of data on it and it returns in a second when I have the Currency Report Option slicer on the report, but nothing selected. As soon as I select the CD option it is spinning forever and not returning.
How can I adjust this DAX measure so that it performs well.

Iterative functions tend to be expensive. How about refactoring like this?
Amount =
SWITCH (
SELECTEDVALUE ( 'Report Options'[Currency], "CD" ),
"USD", SUM ( 'Financial All Scenarios'[GLAmountUSD] ),
"CD", SUM ( 'Financial All Scenarios'[GLAmountCD] ),
SUM ( 'Financial All Scenarios'[GlAmountDoc] )
)

Related

DAX Measure (e.g., "Count Rows") based upon filtered measure value (e.g., "[Sales]>100")

I need to write a DAX measure that calculates (e.g., "Count Rows"), but only when another measure value is evaluated (e.g., filtering "[Sales]>100"). So if-- in the context of the selected filters-- Sales is great than 100, then the measure is executed only for those rows.
The measure I have defined works in the context of lower smaller grain. But the totals do not sum correctly.
Any suggestions?
DAX Measure
License Usage =
// Users with active viewership in 3 months
IF (
NOT ( ISBLANK (
CALCULATE (
[Activity Date NEWEST],
KEEPFILTERS ( DATESINPERIOD ( dimCalendar[Date], TODAY (), -90, DAY ) )
)
)), 1
)
Activity Date NEWEST =
MAX('PBI Activity'[Date])
Okay, I figured something out that works.
DAX
License Usage =
// Users with active viewership in 3 months
CALCULATE (
[Count Users],
FILTER ( 'PBI Activity', 'PBI Activity'[Date] >= TODAY () - 90 )
)
Count Users = COUNTROWS('Users')
Also, I later came across this article which looks like it also does what I was hoping to do: Execute calculate expression over filtered rows based upon measure filter.
Reference: Specifying multiple filter conditions in CALCULATE - SQLBI
DAX
DEFINE
MEASURE Sales[Big Sales Amount] =
CALCULATE (
[Sales Amount],
KEEPFILTERS (
FILTER (
ALL ( Sales[Quantity], Sales[Net Price] ),
Sales[Quantity] * Sales[Net Price] > 1000
)
)
)
EVALUATE
SUMMARIZECOLUMNS (
Sales[Quantity],
"Sales Amount", [Sales Amount],
"Big Sales Amount", [Big Sales Amount]
)

Running total with a slicer in Powerbi

I am trying to find the running total by month, it worked using the following measure but only without using a slicer for the category "BLK":
With Date = VAR MaxDate =
MAX ( 'Calendar Table'[Date] ) RETURN
CALCULATE (
SUM ( 'Injuries'[Total] ),
FILTER (
ALL ( 'Injuries'[Classification] ),
'Injuries'[Classification] = "FAC"
),
FILTER ( ALLSELECTED ( 'Calendar Table' ), 'Calendar Table'[Date] <= MaxDate)
)+0
The result was only accurate when I don't apply the Category slicer "BLK", I tried a different measure:
With BLK = CALCULATE( SUM('Oxy Oman Personal Injuries'[Total]),
FILTER (
ALL ( 'Injuries'[Classification] ),
'Injuries'[Classification] = "FAC"
), ALLSELECTED('Blocks'[BLK]) )+0
The above gave me something similar to the actual data, it did not sum up the numbers.. at least it gave me the correct total of a the category selected = 5 while the first measure gave the total wrong = 4.
Here is a screenshot of the results for both measures with and without a slicer:
Without BLK slicer:(With Data gave me what I wanted)
Using one Category in the BLK Slicer:
How can I fix that?

How to dynamic change the filter in Power BI DAX based on a selected filter

I have a table that people use in a filter and select multiple items from the for example the values in this table are
US Dollar
Canadian Dollar
Category 1
Category 2
The users will select US Dollars and Calendar Year, which I need to affect a 2 DAX measures. The first measure should be the sum 1 of 2 different columns, something similar to
Currency Amount = CALCULATE(
if(SELECTEDVALUE('Filter'[Description])="USD",
Sum(Test[USD Amount]),
Sum(Test[CD Amount])
))
Then the second measure should be something similar to the below, but what is below doesn't work and I'm fairly certain there is a better way to write this overall:
Currency Category Amount =
if(SELECTEDVALUE('Filter'[Description])="Cat 1",
CALCULATE(
[Currency Amount],
Filter(Test, Test[Category]="Cat 1")),
CALCULATE(
[Currency Amount],
Filter(Test, Test[Category]="Cat 2"))
)
The problem with this is that the slicer is multi select and the Selected Value function doesn't appear to work correctly with this.
I have come up with the following that matches what I'm looking for. If somebody can come up with a better solution I will gladly accept that instead. The main this I don't like about this is the duplication of the entire things. As I mentioned in the comment the actual filter that I would be using is much more complex, something more along the lines what is below.
Currency Category Amount = if(
Contains(Values('Filter'[Description]), 'Filter'[Description], "Cat 1"),
CALCULATE(
[Currency Amount],
Filter(Test, Test[Category]="Cat 1")),
CALCULATE(
[Currency Amount],
Filter(Test, Test[Category]="Cat 2"))
)
Cat 1
FILTER (
ALL ( 'Calendar' ),
'Calendar'[Month In Fiscal Year] <= MAX ( 'Calendar'[Month In Fiscal Year] )
&& 'Calendar'[Fiscal Year] = MAX ( 'Calendar'[Fiscal Year] )
)
Cat 2
FILTER (
ALL ( 'Calendar' ),
'Calendar'[Month In APY] <= MAX ( 'Calendar'[Month In APY] )
&& 'Calendar'[APY] = MAX ( 'Calendar'[APY] )
)
A way to have less code repetition is to encapsulate some of the calculations in different measures, in this way, if you need the same calculation logic you can just use the appropriate measure (the logic will be centralized in one point).
I've used the SWITCH (TRUE(), ...) to choose the appropriate measure since it allows you to have a cleaner code if the options are more than 2, and to set a default result if there are no selections or if the selected value is not valid/mapped.
Note that there might be some syntax errors since I don't have a datamodel to validate the formulas.
Currency Amount = CALCULATE(
--you probably have already replaced this with something different from SELECTEDVALUE
--If more than 2 currency exists, using SWITCH might be better (Pros above)
if(SELECTEDVALUE('Filter'[Description])="USD",
Sum(Test[USD Amount]),
Sum(Test[CD Amount])
))
Amount YTD (Fiscal Cal) =
CALCULATE(
[Currency Amount]
,ALL ( 'Calendar' )
,'Calendar'[Month In Fiscal Year] <= MAX ( 'Calendar'[Month In Fiscal Year] )
&& 'Calendar'[Fiscal Year] = MAX ( 'Calendar'[Fiscal Year] )
)
Amount YTD (APY) =
CALCULATE(
[Currency Amount]
,ALL ( 'Calendar' )
,'Calendar'[Month In APY] <= MAX ( 'Calendar'[Month In APY] )
&& 'Calendar'[APY] = MAX ( 'Calendar'[APY] )
)
Currency Category Amount =
SWITCH(
TRUE()
,Contains(Values('Filter'[Description]), 'Filter'[Description], "Cat 1")
,[Amount YTD (Fiscal Cal)]
,Contains(Values('Filter'[Description]), 'Filter'[Description], "Cat 1")
,[Amount YTD (APY)]
,BLANK() --If nothing match return blank (remove it if not needed)
)
I've noticed that your 'Filter' table contains several entities (currency, year/month), if viable/appropriate, splitting it into several filter tables 'FilterCurrency', 'FilterPeriod', etc... might help you by enabling the "always one selected" in slicers, Which in some cases is very useful.

Using summarize and userelationship to generate a sum based on a condition

Story:
I have two date columns in my fact table, one is for orderdate and the second is for orderdate/refund/cancelled date.
I created two relationships between the date table and the fact table.
Active: Date > OrderDate
Inactive: Date > OtherDate
I would like to sum the # of refunds per day using the inactive relationship.
What I tried:
Returns =
VAR summary =
SUMMARIZE (
FILTER ( Query1, Query1[kind] = "refund" ),
Query1[orderId],
"returns", MAX ( Query1[amount] )
)
RETURN
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
summary
)
For some reason, it's using the active date column. Any suggestion on how to fix the above formula?
I'm not sure I understand how you are intending to use the summary variable here, but note that USERELATIONSHIP doesn't affect it at all since it's already computed.
You might not need that variable at all. Try this:
Returns =
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
Query1[kind] = "refund"
)

DAX: Average distinct values per day

I've got some categories spread over a number of days. The same category can occur several times on the same date. How can I get the average number of distinct categories per day?
Dataset:
Date,Category
11.10.2018,A
11.10.2018,B
11.10.2018,C
12.10.2018,A
12.10.2018,A
12.10.2018,A
13.10.2018,B
13.10.2018,B
Table from data view:
Table visualization:
My attempt:
I'm able to get distinct values per day as a measure using dist = CALCULATE(DISTINCTCOUNT(Table1[Category]);DISTINCT(Table1[Date]))
So what I'd like to end up with is the average of dist in the table above which is 1.67. But how do you do that? I've tried different combinations with AVERAGE, AVAREGEX, VALUES and CALCULATE, but with no luck. And the more I try, the more I convince myself that DAX is useless (even though I know deep down it can't be). Thank you for any suggestions!
Use SUMMARIZE to calculate the distinct count for each date, then you can use AVERAGEX to iterate over each date value:
dist:=
IF (
HASONEFILTER ( Table1[Date] ),
DISTINCTCOUNT ( Table1[Category] ),
AVERAGEX (
SUMMARIZE (
Table1,
Table1[Date],
"Daily Average", DISTINCTCOUNT ( Table1[Category] )
),
[Daily Average]
)
)
EDIT: You don't really need the IF function - it seems to perform just as well using simply:
dist:=
AVERAGEX (
SUMMARIZE (
Table1,
Table1[Date],
"Daily Average", DISTINCTCOUNT ( Table1[Category] )
),
[Daily Average]
)