How to different calculation on different granularity? - powerbi

I want to achieve the following:
The idea is to calculate the sum product in the following scenario:
When calculating the subtotal (that is on the Level1 granularity) the formula is: the sum of Wieght2 * Amount.
When calculating the grand total, the formula is: the sum of Wieght1 * subtotal.
How can I achieve that in DAX?!

It depends a bit on how your data model looks...
With a model like this:
Your DAX measure may look something like this:
Weighted Amount =
SWITCH (
TRUE(),
ISINSCOPE ( Level2[Level 2] ),
SELECTEDVALUE ( Level2[Amount] ),
ISINSCOPE ( Level1[Level 1] ),
SUMX (
Level2,
Level2[Amount] * Level2[Weight 2]
),
SUMX (
Level1,
CALCULATE (
SUMX (
Level2,
Level2[Amount] * Level2[Weight 2]
)
) * Level1[Weight 1]
)
)
We're using SWITCH and ISINSCOPE to determine the level at which the measure is being evaluated, then following your business logic for each level.

Related

Refactor DAX code that utilises SUMX and SUMMARIZE

I have a DAX code that I know can be hugely improved on in terms of efficiency and performance but I'm not quite sure how to go about it.
Total GMRR (EUR) =
SUMX (
FILTER (
SUMMARIZE (
fact_transaction_monthly,
dim_partner[partner_created_date],
dim_partner[partner_name],
"GMRR", SUM ( fact_transaction_monthly[euroConsolidatedGMRR] ),
"check", [checkActive]
),
[check] = 1
),
[GMRR]
)
I am creating a summary table and summing over the values where the check is equal to 1 but this is taking a long time to compute
Check Active Code:
checkActive =
IF ([Total Active Partners] = 1,1,0)
Total GMRR (EUR) =
SUMX (
CALCULATETABLE (
SUMMARIZE (
fact_transaction_monthly,
dim_partner[partner_created_date],
dim_partner[partner_name],
"GMRR", SUM ( fact_transaction_monthly[euroConsolidatedGMRR] )
),
[checkActive] = 1
),
[GMRR]
)

average divided by the count per project

I have three tables time, SectorProject, product Project.
Time AS(
SELECT *
FROM (VALUES(1011,48),(201,520),(36,120))V(id_project,time)),
SectorProject AS(
SELECT *
FROM (VALUES(1011,'BM'),(1011,'Fi'),(1011,'Om'),(201,'BM'),(36,'BM'))V(id_project,Sector1)),
prductProject AS(
SELECT *
FROM (VALUES(1011,'bike'),(1011,'velo'),(1011,'pc'),(201,'n'),(36, 'r' ))V(id_project,product))
I need to calculate average divided by the count per project
With sql server it will something like the following code:
avg( sum(time)) over (partition by t.id_project) * 1.0 / count(*) over (partition by t.id_project)
How to do the same thing within Dax.
You should look for "sum by category" to find the correct DAX pattern.
SumOverPartition:=
CALCULATE (
SUM ( T[Sales] ),
REMOVEFILTERS ( 'T' ),
VALUES ( T[Category] )
)
CountOverPartition:=
CALCULATE (
COUNTROWS ( T ),
REMOVEFILTERS ( 'T' ),
VALUES ( T[Category] )
)
You could also achieve it with ALLEXCEPT function but the pair REMOVEFILTERS and VALUE is better. Learnt the hard way.
https://www.sqlbi.com/articles/using-allexcept-versus-all-and-values/
In that article, they use the archaic name ALL instead of REMOVEFILTERS.
If you want it in calculated column, then you have to wrap it with another CALCULATE.
SumOverPartition:=
CALCUALTE
CALCULATE (
SUM ( T[Sales] ),
REMOVEFILTERS ( 'T' ),
VALUES ( T[Category] )
)
)

Return date based on a condition in Power BI using DAX

hope you can help me.
I need to calculate in Power BI a date difference between today() and a certain date based on a condition.
I have a calendar table with the date (calendario[fecha]) related to a fact table ASID to predict column ASID[amount] and a measeure [Estimado] that gives me the linear regression
Estimado =
VAR Known =
FILTER (
SELECTCOLUMNS (
ALLSELECTED ( 'calendario'[fecha] ),
"Known[X]", calendario[fecha],
"Known[Y]", [ASID]
),
AND (
NOT ( ISBLANK ( Known[X] ) ),
NOT ( ISBLANK ( Known[Y] ) )
)
)
VAR Count_Items =
COUNTROWS ( Known )
VAR Sum_X =
SUMX ( Known, Known[X] )
VAR Sum_X2 =
SUMX ( Known, Known[X] ^ 2 )
VAR Sum_Y =
SUMX ( Known, Known[Y] )
VAR Sum_XY =
SUMX ( Known, Known[X] * Known[Y] )
VAR Average_X =
AVERAGEX ( Known, Known[X] )
VAR Average_Y =
AVERAGEX ( Known, Known[Y] )
VAR Slope =
DIVIDE (
Count_Items * Sum_XY - Sum_X * Sum_Y,
Count_Items * Sum_X2 - Sum_X ^ 2
)
VAR Intercept =
Average_Y - Slope * Average_X
RETURN
ROUND(
SUMX (
DISTINCT ( calendario[fecha] ),
Intercept + Slope * calendario[fecha]
),0)
My visualization matrix has 3 columns: calendario[fecha], it's real value [ASID] and the estimated measure [Estimado].
I have a limit of 1105 for that ASID.
I can see that at a future day, let's say a month from now 03/12/2020, the estimated reaches a value of 1105 (after scrolling all the matrix), so I need a way to capture that day and be able to calculate 03/12/2020 - today() and display somewhere: "30 days left"
Raihan: I could use the datediff as you suggested
matrix
Is there a way to capture just the 231 value?
DAX is now: if([Estimado]>1105, DATEDIFF(TODAY(),LASTDATE(calendario[fecha]),DAY),0)
As you didn't provide the sample dataset and you didn't tell about your measure formula I just consider a sample dataset on my own to simulate your problem.
Consider following screenshot with data and calculated columns.
Here the DaysFromToday calculate the Day difference from Today to for every column if the corresponding value in 'SomeValue' field reached a certain number. SomeValue is also calculated field that you can replace with your own calculation.
To get the single value from DaysFromToday you can have a measure which will give you MAX or MIN (of course some others functions if you need) of the column values like following screenshot -
Yellow highlighted is the DAX way of mentioning a field name with the table name that you are missing in your formula.
Lastly the MAX or MIN measure can be displayed in the report like following -
it will be better if you can provide sample dataset and sample answer that you want.

Issue trying to calculate gradient using Power BI

I am trying to calculate the gradient of the trendline passing through a series of points contained within my dataset. I have researched to see if there are built in functions to do this and there doesn't seem to be, so I am doing it manually. I'm not a DAX expert (nor probably a maths expert either!).
I have created a table in excel to walk through a simple example so I know what I'm aiming for:
In the Power BI environment, there are two tables joined on the "Month&Year" columns. An abridged illustration of these tables is below:
Please note the "Orders" measure from the illustration is referred to as "Special orders per day" in the Power BI code.
Step 1
Create the measure that averages the month numbers:
Average of months =
- AVERAGEX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"AvMonths", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
[AvMonths]
)
I use AVERAGE in the expression part so that the record for Sept-2018 has a 21 in the "AvMonths" column and then for Oct-2018 it says 22. I guess I could have used MIN or MAX because they will all say 21 or 22 depending on the month (only one to avoid would be SUM as this would add them all up).
I also tried to do this by summarizing and then creating a NATURALLEFTOUTERJOIN to the User_Friendly_Months table to get the month number for these months and when incorporating that into the rest of this procedure the measure took forever to calculate (even though it actually worked in the end somehow).
Step 2
Do the same for orders:
Average of special orders =
- AVERAGEX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day]
),
[Special OPD]
)
Step 3
Perform the calculation that goes through to step "C" in my original picture:
Column_C_Step =
SUMX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day],
"MonthNum", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
( [Special OPD] + [Average special orders] )
* ( [MonthNum] + [Average of MonthNums] )
)
Instead of returning -11.95 in my example, the measure returns zero.
When I do this:
Check_orders_worked =
SUMX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day],
"MonthNum", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
[Special OPD]
)
...I get 1188.9, which is the total of "Orders" in my Excel table illustration (so must be working).
When I do this:
Check_months_worked =
SUMX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day],
"MonthNum", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
[MonthNum]
)
...I get 43, which is the total of Month_Num in my illustration (so again, must be working).
But when I attempt to perform the equivalent of a SUMPRODUCT on A and B to get C, it returns zero.
Can anyone shed any light on what on earth is going on??
It is driving me insane.
Or if there is a simpler way to do a gradient calculation I will cry with joy.
Thank you
UPDATE
For completeness here is the measure that worked:
Step_C_Measure =
VAR _OrdersAverage = [Average special orders]
VAR _MonthsAverage = [Average of MonthNums]
RETURN
SUMX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day],
"MonthNum", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
( [Special OPD] + _OrdersAverage )
* ( [MonthNum] + _MonthsAverage )
)
Then Step D:
Step_D_Measure =
VAR _MonthsAverage = [Average of MonthNums]
RETURN
SUMX (
SUMMARIZE (
CALCULATETABLE ( Query_GSR, ALLSELECTED ( User_Friendly_Months ) ),
Query_GSR[Month&Year],
"Special OPD", [Special orders per day],
"MonthNum", AVERAGE ( Query_GSR[MonthNumForSlope] )
),
( [MonthNum] + _MonthsAverage )
* ( [MonthNum] + _MonthsAverage )
)
And finally to get the gradient:
Special order gradient =
DIVIDE ( Step_C_Measure, Step_D_Measure, "" )
In a question about multiple linear regression, I linked to a community post that covers basic linear regression.
In your case, the formula for the slope can be calculated similar to this:
Slope =
VAR RowCount = COUNTROWS(Query_GSR)
VAR Sum_X = SUMX(Query_GSR, Query_GSR[Month_Num])
VAR Sum_Y = SUMX(Query_GSR, Query_GSR[Orders])
VAR Sum_XY = SUMX(Query_GSR, Query_GSR[Month_Num] * Query_GSR[Orders])
VAR Sum_XX = SUMX(Query_GSR, Query_GSR[Month_Num] * Query_GSR[Month_Num])
RETURN DIVIDE(RowCount * Sum_XY - Sum_X * Sum_Y, RowCount * Sum_XX - Sum_X * Sum_X)
This works for a regression on multiple months, not just two.

Power BI: Quarter over Quarter %Change

To start, here is the Power BI I am working with:
I want to calculate the %Change in Cost Quarter over Quarter.
As shown in the table above, I have the Cost Total for Q1, Q2, Q3, and Q4 in the Total Cost by Quarter Column, which I calculated using this formula:
Total Cost By Quarter =
IF (
[Quarters] = "Q1",
CALCULATE (
SUM ( CR_Months_ByMonth[Cost] ),
FILTER ( CR_Months_ByMonth, [Quarters] = "Q1" )
),
IF (
[Quarters] = "Q2",
CALCULATE (
SUM ( CR_Months_ByMonth[Cost] ),
FILTER ( CR_Months_ByMonth, [Quarters] = "Q2" )
),
IF (
[Quarters] = "Q3",
CALCULATE (
SUM ( CR_Months_ByMonth[Cost] ),
FILTER ( CR_Months_ByMonth, [Quarters] = "Q3" )
),
IF (
[Quarters] = "Q4",
CALCULATE (
SUM ( CR_Months_ByMonth[Cost] ),
FILTER ( CR_Months_ByMonth, [Quarters] = "Q4" )
)
)
)
)
)
However, I could not figure out how to calculate %Change between quarters using another Calculated column, due to the repeating values (multiple Q1s, Q2s, etc in [Total Cost By Quarter]).
So, I attempted to calculate the %Change using Measures.
I made a measure for the Q1 Cost, Q2 Cost, Q3 Cost, and Q4 Cost, using a formula like the one below:
Q1Sum =
CALCULATE (
SUM ( CR_Months_ByMonth[Cost] ),
FILTER ( CR_Months_ByMonth, [Quarters] = "Q1" )
)
I then made a new measure to calculate Q12%Change, Q23%Change, and Q34%Change, using a formula like the one below:
Q12%Change =
( DIVIDE ( [Q2Sum] - [Q1Sum], [Q1Sum] ) )
* 100
This is the result that I get using the calculated measures:
This structure does not yield good visuals and I am certain there is a simpler, more efficient way to accomplish Quarter over Quarter %Change.
This is my desired result:
As a final note, I do have a date table that looks like this:
THANK YOU!
[Total Cost by Quarter] should be as simple as SUM(CR[Cost]) if placed into a matrix that has quarters on the rows/columns.
The trickier part is referencing the previous quarter to get the percent change. It will look something like this:
% Change =
VAR PrevQtrCost = CALCULATE(SUM(CR[Cost]), PREVIOUSQUARTER(DateTable[Date]))
RETURN DIVIDE(SUM(CR[Cost]), PrevQtrCost) - 1
The VAR line might be a bit different depending on how exactly you have your DateTable related to the CR table.
Also take a look at this similar question: Power BI: Percent Change Formula
If you aren't linking on a date, then try something along these lines:
% Change =
VAR PrevQtr = MOD(MAX(DateTable[FiscalQuarterNumber]) - 2, 4) + 1
VAR PrevQtrCost = CALCULATE(SUM(CR[Cost]), DateTable[FiscalQuarterNumber] = PrevQtr)
RETURN DIVIDE(SUM(CR[Cost]), PrevQtrCost) - 1