Creating calculated table with MAX and MIN dates in DAX Power BI - filter

I have the following table, imported in Power BI - QOL_Exp (see screenshot example below)
I need to create a calculated table which will filter out values, where Rating = 999 and,
at the same time, will pick only the highest and the lowest Date values from Date column, based on ClientID (see highlighted grey and peach colored areas).
I highlighted in red font - the values that I expect to see in my calculated table
For example, for ClientID = 3052 I will need the records where Date = 11/20/2020 (lowest date for this ClientID) and Date = 5/17/2021 (highest date for this ClientID)
For ClientID = 2666 I will not need the record where Rating = 999 (one of the conditions)
I managed to filter out (to exclude Rating = 999) but struggling with including only Max and MIN date in the new calculated table
This is my DAX:
QOL = CALCULATETABLE(QOL_Exp, QOL_Exp[Rating]<>999)
How should I modify it in order to only leave Max(Date) and Min(Date) records, based on ClientID?
UPD:
Based on the answer given, slightly updated (see below):
QOL =
FILTER (QOL_Exp, QOL_Exp[Rating] <> 999
&&
(( QOL_Exp[Date] = CALCULATE (MIN ( QOL_Exp[Date] ),
ALLEXCEPT(QOL_Exp,QOL_Exp[ClientID])))
|| QOL_Exp[Date] = CALCULATE (MAX ( QOL_Exp[Date] ),
ALLEXCEPT(QOL_Exp, QOL_Exp[ClientID]))))

QOL =
FILTER (
QOL_Exp,
QOL_Exp[Rating] <> 999
&& (
QOL_Exp[Date]
= CALCULATE (
MIN ( QOL_Exp[Date] ),
FILTER (
QOL_Exp,
QOL_Exp[Rating] <> 999
&& QOL_Exp[ClientID] = EARLIER ( QOL_Exp[ClientID] )
)
)
|| QOL_Exp[Date]
= CALCULATE (
MAX ( QOL_Exp[Date] ),
FILTER (
QOL_Exp,
QOL_Exp[Rating] <> 999
&& QOL_Exp[ClientID] = EARLIER ( QOL_Exp[ClientID] )
)
)
)
)

Related

Calculate the difference between the current and the previous row in DAX

In Analysis Services I have a table for Covid Cases, as shown below:
It shows the cumulative cases on a daily basis for 193 different countries. I would like to add a calculated column to calculate the difference between the current row and the previous row, so I can see the daily new cases. Also, as column Country/Region contains 193 different countries, this calculation needs to be somehow grouped for each country. The Date column should also be in the right order.
How should I sort the table and what DAX function should I use to make this work?
Try this
Column =
VAR current =
CALCULATE ( MAX ( tbl[Value] ) )
VAR prev =
MAXX (
FILTER (
tbl,
tbl[Country] = EARLIER ( tbl[Country] )
&& tbl[Date] < EARLIER ( tbl[Date] )
),
tbl[Value]
)
RETURN
current - prev

Microsoft Power BI - DAX Time Intelligence measure - change context to reflect proper % change; non-YTD measures

I have a Power BI visual as below. There are 3 matrices. I have a DateDimension (or) Calendar table called Dates2.
I use two measures, one a regular measure (called 'Count'), the other a parallel period comparison of the measure (called 'Count_PreviousYear'). I use SAMEPERIODLASTYEAR DAX function for the latter.
1)
Count = COUNTA(TableX[ColumnY])
--Measure with name 'Count'--
2)
Count_PreviousYear = CALCULATE
(
[Count],
SAMEPERIODLASTYEAR(Dates2[Date])
)
--Measure with name 'Count_PreviousYear'
--this measure uses Time Intelligence function - SAMEPERIODLASTYEAR--
Both 'Count' and 'Count_PreviousYear' (obviously) are not YTD (YearToDate) values.
A third measure for the percentage change across periods is computed as below:
3)
PercentageChange = IF(
ISBLANK([Count]) || ISBLANK([Count_PreviousYear]),
BLANK(),
(([Count] - [Count_PreviousYear])/[Count])
)
Kindly ignore the fact that a keyword used as a measure name;
I have used the name 'Count' only for clarity; in my actual report,
I have proper names
The % change measure works fine, but one issue:
For the period change from 2020 to 2021, i.e. in the third row of the last matrix (for the row value 2021), the total (i.e. the % change value) is not appropriate.
I need to replace -737.21% with - 23.98 %.
This is because , I need to compute the Total for 2020, only by adding the values for the months of January and February, i.e. 428 + 430 = 858. (not 5794, which is for all the 12 months).
Since 2021 has only two months - January and February, I don't want to compare two months of 2021, with all the 12 months of 2020. Rather, I want two months of 2021 to be compared with the corresponding 2 months of 2020.
Essentially I need {(692-858)/692} * 100 = -23.98%
Currently, I see {(692-5794)/692} * 100 = -737.21%
Can someone help me achieve this?
Count Previous Year =
IF (
HASONEVALUE ( Dates2[Month] ),
IF (
[Count] <> BLANK (),
CALCULATE ( [Count], SAMEPERIODLASTYEAR ( Dates2[Date] ) )
),
IF (
HASONEVALUE ( Dates2[Year] ),
CALCULATE (
[Count],
DATESBETWEEN (
Dates2[Date],
EDATE ( MIN ( Dates2[Date] ), -12 ),
EOMONTH ( MAX ( [FactTable[Date] ), -12 )
)
)
)
)
Count_PreviousYear = IF (
(HASONEVALUE(Dates2[Year]) = TRUE && HASONEVALUE(Dates2[MonthName]) = TRUE),
CALCULATE
(
[Count],
SAMEPERIODLASTYEAR(Dates2[Date])
),
IF (
(HASONEVALUE(Dates2[Year]) = TRUE && HASONEVALUE(Dates2[MonthName]) = FALSE),
CALCULATE (
[Count],
DATESBETWEEN (
Dates2[Date],
EDATE (MIN(Dates2[Date]), -12),
EOMONTH (MAX(SourceData[Date]), -12)
)
),
BLANK()
)
)
!Output obtained as desired]1

DAX Measure to Calculate Total Yearly Forecast by Snapshot Period

I want to recreate a sumifs dax measure (not calculated column) to Sum Yearly Totals for each snapshot period (less than or equal to selected slicer Month End) by (forecast)month and Productcategory
In Excel this would be accomplished with the following sumifs function =SUMIFS($D$2:$D$97,$A$2:$A$97,B2,$C$2:$C$97,C2)
That is sum amount if reporting period equals value of month in current table row and category equals value of category in current table row
Table fields:
Snapshot Date (range from 31JAN2020 to 31DEC2020 by month end)
Forecast for Month (range from 31JAN2020 to 31DEC2020 by month end)
Sub Category (bikes, coats)
Amount (number actual sales mtd or projected count of sales)
Type (Actual or projection) actual sales amount to date, or projected for each month to end of year
Snapshot Date,Forecast for Month,Sub Category,Amount,Type,Expected Result fo 31MAR2020
1/31/2020,1/31/2020,Bikes,3,Actual,133
1/31/2020,2/29/2020,Bikes,7,Projection,138
1/31/2020,3/31/2020,Bikes,11,Projection,0
1/31/2020,4/30/2020,Bikes,20,Projection,0
1/31/2020,5/31/2020,Bikes,10,Projection,0
1/31/2020,6/30/2020,Bikes,11,Projection,0
1/31/2020,7/31/2020,Bikes,20,Projection,0
1/31/2020,8/31/2020,Bikes,20,Projection,0
1/31/2020,9/30/2020,Bikes,2,Projection,0
1/31/2020,10/31/2020,Bikes,9,Projection,0
1/31/2020,11/30/2020,Bikes,18,Projection,0
1/31/2020,12/31/2020,Bikes,2,Projection,0
1/31/2020,1/31/2020,Coats,1,Actual,111
1/31/2020,2/29/2020,Coats,8,Projection,136
1/31/2020,3/31/2020,Coats,10,Projection,0
1/31/2020,4/30/2020,Coats,17,Projection,0
1/31/2020,5/31/2020,Coats,12,Projection,0
1/31/2020,6/30/2020,Coats,1,Projection,0
1/31/2020,7/31/2020,Coats,11,Projection,0
1/31/2020,8/31/2020,Coats,4,Projection,0
1/31/2020,9/30/2020,Coats,16,Projection,0
1/31/2020,10/31/2020,Coats,10,Projection,0
1/31/2020,11/30/2020,Coats,10,Projection,0
1/31/2020,12/31/2020,Coats,11,Projection,0
2/29/2020,1/31/2020,Bikes,3,Actual,133
2/29/2020,2/29/2020,Bikes,17,Actual,138
2/29/2020,3/31/2020,Bikes,7,Projection,0
2/29/2020,4/30/2020,Bikes,17,Projection,0
2/29/2020,5/31/2020,Bikes,11,Projection,0
2/29/2020,6/30/2020,Bikes,11,Projection,0
2/29/2020,7/31/2020,Bikes,18,Projection,0
2/29/2020,8/31/2020,Bikes,17,Projection,0
2/29/2020,9/30/2020,Bikes,3,Projection,0
2/29/2020,10/31/2020,Bikes,13,Projection,0
2/29/2020,11/30/2020,Bikes,9,Projection,0
2/29/2020,12/31/2020,Bikes,12,Projection,0
2/29/2020,1/31/2020,Coats,15,Actual,111
2/29/2020,2/29/2020,Coats,7,Actual,136
2/29/2020,3/31/2020,Coats,15,Projection,0
2/29/2020,4/30/2020,Coats,11,Projection,0
2/29/2020,5/31/2020,Coats,1,Projection,0
2/29/2020,6/30/2020,Coats,12,Projection,0
2/29/2020,7/31/2020,Coats,9,Projection,0
2/29/2020,8/31/2020,Coats,13,Projection,0
2/29/2020,9/30/2020,Coats,2,Projection,0
2/29/2020,10/31/2020,Coats,16,Projection,0
2/29/2020,11/30/2020,Coats,19,Projection,0
2/29/2020,12/31/2020,Coats,16,Projection,0
Any help would be appreciated
This is a possible measure that emulates the sumifs expression.
It work at the level of the single row and returns BLANK() if more than one row is in the current filter context
Result =
VAR SelectedMonth =
SELECTEDVALUE ( Snapshot[Forecast for Month] )
VAR SelectedSubCategory =
SELECTEDVALUE ( Snapshot[Sub Category] )
RETURN
IF (
NOT ISBLANK ( SelectedMonth )
&& NOT ISBLANK ( SelectedSubCategory ),
CALCULATE (
SUM ( Snapshot[Amount] ),
REMOVEFILTERS ( Snapshot ),
Snapshot[Snapshot Date] = SelectedMonth,
Snapshot[Sub Category] = SelectedSubCategory
) + 0
)

Calculating payback period using DAX

I'm working on some calculations for capital budgeting, and I have the following two tables in my data model
I'm trying to build out a calculated column in DAX to determine the payback period for each project in the Project table. I've put together the calculation here, I'm just not sure exactly how to execute this in DAX.
Logical Steps for Calculating Payback Period:
For each Project, find the cumulative sum for each date for relevant metrics (Include OpEx Savings and OpEx Implementation Cost, but not Revenue or Working Capital)
Find the MIN date where cumulative sum is greater than zero (the "break-even" date")
Find the MIN date with non-zero implementation cost ("Investment date")
Find the difference (in months) between #2 and #3 to determine payback period
EDIT:
The answer for the listed project is 7 months. I've built an intermediate table in Excel to develop the answer, but I'd like to be able to do this directly in a PowerPivot table with DAX.
I've produced this as a solution:
Create values, which makes sure cost are - and savings are + (ValCorr)
Create a running sum (RunningSum)
Find Investment Date (InvestmentDate)
Find Breakeven Date (BreakEvenDate)
Find Difference (Payback)
DAX:
RunningSum =
CALCULATE(SUM(Impacts[ValCorr]);
FILTER(
ALL(Impacts);
Impacts[ProjectID] = EARLIER(Impacts[ProjectID]) &&
Impacts[Date] <= EARLIER(Impacts[Date])
))
InvestmentDate =
CALCULATE (
FIRSTNONBLANK ( Impacts[Date]; 0 );
FILTER ( ALL ( Impacts ); Impacts[RunningSum] <> 0 )
)
BreakEvenDate =
CALCULATE (
FIRSTNONBLANK ( Impacts[Date]; 0 );
FILTER ( ALL ( Impacts ); Impacts[RunningSum] > 0 )
)
Payback = DATEDIFF(Impacts[InvestmentDate];Impacts[BreakEvenDate];MONTH)
Result:
Good luck!
After a fair amount of trial and error, I came up with a solution.
Step 1: Build out a helper metrics table. This serves 2 purposes: (a) excludes irrelevant metrics (like revenue), and (b) ensure costs are negative and savings are positive.
Metrics Table
Step 2: Build 2 helper measures that will go into the virtual, summarized, intermediate table.
CumulativeTotalMetric :=
CALCULATE (
SUMX (
Impact,
Impact[Latest Estimate Monthly Values]
* RELATED ( BaseMetrics[Payback Period Multiplier] )
),
FILTER ( ALL ( Impact[Month] ), Impact[Month] <= MAX ( Impact[Month] ) )
)
TotalMetric :=
SUMX (
Impact,
Impact[Latest Estimate Monthly Values]
* RELATED ( BaseMetrics[Payback Period Multiplier] )
)
Step 3: Create the final measure that creates the virtual table (BaseTable), and performs logical operations on it to arrive at the final payback period.
Payback Period (Years) :=
VAR BaseTable =
ADDCOLUMNS (
SUMMARIZE ( Impact, Impact[initiative #], Impact[snapshot], Impact[Month] ),
"Cumulative Total Impact", CALCULATE ( [CumulativeTotalMetric] ),
"Total Impact", CALCULATE ( [TotalMetric] )
)
VAR LastCumulativeLossDate =
MAXX ( FILTER ( BaseTable, [Cumulative Total Impact] < 0 ), [Month] )
VAR BreakEvenDate =
MINX (
FILTER (
BaseTable,
[Month] > LastCumulativeLossDate
&& [Cumulative Total Impact] > 0
),
[Month]
)
VAR InitialInvestmentDate =
MINX ( FILTER ( BaseTable, [Total Impact] < 0 ), [Month] )
RETURN
IF (
OR ( ISBLANK ( InitialInvestmentDate ), ISBLANK ( BreakEvenDate ) ),
BLANK (),
( BreakEvenDate - InitialInvestmentDate )
/ 365
)
This last meaure is pretty complicated. It uses progressive, dependent variables. It starts with the same base table, and defines variables that are used in subsequent variables. I'm no DAX expert, but I suspect using these variables helps with the calculation efficiency.
EDIT: I should note that I didn't use this measure as a calculated column -- I simply used it in a pivot table which is the same "shape" as the "Projects" table above -- one line per project / initiative.

DAX How do I calculate Exchange Rate between two tables?

I have a table Sales with fields: Date, Revenue, and CurrencyCode
I have a table ExchangeRate with fields ValidFrom, ValidTo, ExchangeRate, and CurrencyCode.
I need to multiply revenue by the ExchangeRate, when the sales Date falls between ValidFrom and ValidTo and the CurrencyCode from both tables match.
You can create a calculate column in the Sales table to take the Rate from ExchangeRate table then just multiply Rate by the Revenue value in an additional column or a measure.
Use this expression in the Sales calculated column, I named ExchangeRate
ExchangeRate =
CALCULATE (
MAX ( ExchangeRate[ExchangeRate] ),
FILTER (
FILTER ( ExchangeRate, [CurrencyCode] = EARLIER ( Sales[CurrencyCode] ) ),
[ValidFrom] <= EARLIER ( Sales[Date] )
&& [ValidTo] >= EARLIER ( Sales[Date] )
)
)
Now you can create a measure for multiplying the Rate by the Revenune:
RevenueXRateMeasure = SUM(Sales[Revenue])*SUM(Sales[ExchangeRate])
Or if you prefer a column use:
RevenueXRateColumn = [Revenue]*[ExchangeRate]
Let me know if this helps.

Resources