How to check if current start and end dates are in previous period (start and end dates) - powerbi

I have a tricky problem I am working on. I've made several attempts at capturing the data but have been unsuccessful.
I have a table in Power Bi that looks like this:
The key is in ascending order as well as the StartDate field. I would like to achieve the results in the "Period Overlap Delta" field but have had trouble trying to figure it out.
Basically, I'd like to assign a value of zero to any period (startdate-enddate combination) that is IN a previous period and take the date difference of those "super" periods.
Here is the DAX to produce the table:
Cases = DATATABLE("Key", integer, "StartDate", datetime, "EndDate", datetime
,{
{1, "01/01/2018", "01/10/2018"}
, {2, "01/03/2018","01/03/2018"}
, {3, "01/05/2018","01/07/2018"}
, {4, "01/15/2018","01/16/2018"}
, {5, "01/21/2018","01/24/2018"}
, {6, "01/25/2018", "01/27/2018"}
, {7, "01/25/2018","01/27/2018"}
})
Thanks so much in advance!!!

We need to know whether or not a certain row is overlapped by a previous row. By previous we mean the key is smaller than current row. By overlapped we mean the StartDate is earlier or equal to current row and EndDate is later or equal to current row, hence:
Overlapped =
COUNTROWS(
FILTER(
'Cases',
'Cases'[StartDate] <= EARLIER('Cases'[StartDate]) &&
'Cases'[EndDate] >= EARLIER('Cases'[EndDate]) &&
'Cases'[Key] < EARLIER('Cases'[Key])
)
)
And with this we just need to wrap it up and calculate the number of days with the DATEDIFF function:
Period Overlap Delta =
VAR Overlapped =
COUNTROWS(
FILTER(
'Cases',
'Cases'[StartDate] <= EARLIER('Cases'[StartDate]) &&
'Cases'[EndDate] >= EARLIER('Cases'[EndDate]) &&
'Cases'[Key] < EARLIER('Cases'[Key])
)
)
RETURN
IF(Overlapped, 0, DATEDIFF('Cases'[StartDate], 'Cases'[EndDate], DAY) + 1)
P.S. The use of DATATABLE to provide sample data is golden and should be promoted more often!

Related

PowerBI: Total Count Distinct

I need some help with my measure counting correct in total.
This is the MainTable:
With my Measure "CountPass" I count every ID distinct with the action "pass":
CountPass = CALCULATE(DISTINCTCOUNT(Workflow[ID]),Workflow[action]="pass")
Furthermore with my Measure CountPassPreweek I do same with reference on previous Week by using the a date table:
CountPassPreweek =
var currentweek = SELECTEDVALUE(DateTable[WeekNum])
var currentweekday = SELECTEDVALUE(DateTable[WeekNo])
var currentyear = SELECTEDVALUE(DateTable[Year])
var maxweeknum = CALCULATE(MAX(DateTable[WeekNum]),all(DateTable))
Return
SUMX(
if(currentweek = 1,
DateTable[WeekNo] = currentweekday && DateTable[WeekNum] = maxweeknum && DateTable[Year] = currentyear - 1,
DateTable[WeekNo] = currentweekday && DateTable[WeekNum] = currentweek -1 && DateTable[Year] = currentyear)),
[CountPass]
)
This is working so far but not showing the totals, so I have a second measure for doing that:
CountPreweekTotal =
var _table = SUMMARIZE(DateTable,DateTable[Date],"_value",[CountPassPreweek])
return
SUMX(_table,[_value])
And here you see my problem: The measure doesn't count distinct like the "original" counting Measure as you see here
Hope somebody can help me with that.
Thanks a lot!
It's counting 3 since abc is getting counted twice the way your measure is written (since dates are separated in your SUMMARIZE).
Since you appear to have a proper date table, you should be able to use time intelligence functions to write this much more simply as
CountPassPreviousWeek =
CALCULATE ( [CountPass], DATEADD ( DateTable[Date], -7, DAY ) )
This should work for the total too.

DAX too slow - scalar value materialization problem

I have the following measure which calculates a node size for a graph chart table:
MEASURE tMeasures[m_ONA_nodeSize_flex] =
IF(
ISBLANK([m_ONA_rankFilter_nodes]),
BLANK(),
var empCnt = ROW(
"data",
CALCULATE(
SUMX( DISTINCT(tONAAppend[id]), 1),
FILTER(
ALL(tONAAppend),
NOT( ISBLANK([m_ONA_rankFilter_nodes]))
)
)
)
RETURN
IF(
empCnt > 25, ROUND( 1500 / empCnt, 0),
60
)
)
[m_ONA_rankFilter_nodes] is used to filter those nodes which exist in edges in the same table. These edges are also filtered using multiple conditions with a measure m_ONA_edgeValue_afterRank, which returns BLANK() if a row doesn't match filters and edge_value if it does.
The script before using tMeasures[m_ONA_nodeSize_flex] with included measures [m_ONA_rankFilter_nodes] and m_ONA_edgeValue_afterRank works relatively fast:
EVALUATE
TOPN(
501,
SUMMARIZECOLUMNS(
'tONAAppend'[tableName],
'tONAAppend'[name],
'tONAAppend'[nameFrom],
'tONAAppend'[nameTo],
'tONAAppend'[id],
'tONAAppend'[idFrom],
'tONAAppend'[idTo],
'tONAAppend'[photoSrc],
__DS0FilterTable,
__DS0FilterTable2,
__DS0FilterTable3,
__DS0FilterTable4,
"m_ONA_edgeValue_afterRank", 'tMeasures'[m_ONA_edgeValue_afterRank],
"m_ONA_rankFilter_nodes", 'tMeasures'[m_ONA_rankFilter_nodes]
),
'tONAAppend'[tableName],
1,
'tONAAppend'[name],
1,
'tONAAppend'[nameFrom],
1,
'tONAAppend'[nameTo],
1,
'tONAAppend'[id],
1,
'tONAAppend'[idFrom],
1,
'tONAAppend'[idTo],
1,
'tONAAppend'[photoSrc],
1
)
However, when I replace 'tMeasures'[m_ONA_rankFilter_nodes] with a 'tMeasures'[m_ONA_nodeSize_flex] it starts working dramatically slower:
EVALUATE
TOPN(
501,
SUMMARIZECOLUMNS(
'tONAAppend'[tableName],
'tONAAppend'[name],
'tONAAppend'[nameFrom],
'tONAAppend'[nameTo],
'tONAAppend'[id],
'tONAAppend'[idFrom],
'tONAAppend'[idTo],
'tONAAppend'[photoSrc],
__DS0FilterTable,
__DS0FilterTable2,
__DS0FilterTable3,
__DS0FilterTable4,
"m_ONA_edgeValue_afterRank", 'tMeasures'[m_ONA_edgeValue_afterRank],
"m_ONA_nodeSize_flex", 'tMeasures'[m_ONA_nodeSize_flex]
),
'tONAAppend'[tableName],
1,
'tONAAppend'[name],
1,
'tONAAppend'[nameFrom],
1,
'tONAAppend'[nameTo],
1,
'tONAAppend'[id],
1,
'tONAAppend'[idFrom],
1,
'tONAAppend'[idTo],
1,
'tONAAppend'[photoSrc],
1
)
As I understand, the problem is in DAX engine working: it tries to calculate the value of this measure for each row. I think the fastest algo could be calculate once, then send to storage, and then populate all rows with it.
How can I optimize and force DAX to work more efficient?
I found good articles which relate to this topic and then implemented approach with variables written there:
https://www.sqlbi.com/articles/optimizing-conditions-involving-blank-values-in-dax/
https://www.sqlbi.com/articles/understanding-eager-vs-strict-evaluation-in-dax/
It worked as expected - all measures put in special variables were materialized in a Storage Engine. The performance has increased dramatically.

DAX PowerBI: Replaced blank values with zero and issue with chart

I tried to create report in Power BI with sales month by month for last 20 months, when sales is blank I want to see month with 0 value.
I decided to change Blank() values with zero adding a 0 at the end of calculation.
It works great, however I have an issue with limitaton date hierarchy, because now my chart contains a lot of months without value (first value begins in 2017, date hierarchy first value begins in 2000).
Test:=
CALCULATE (
SUM( quantity ),
flag = 1,
title = "WEEKS"
) + 0
Instead of a plain 0, you could add an IF to specify to only add that after the first value. Something like this:
Test:=
VAR FirstDate = CALCULATE ( MIN ( date ), ALL( Dates ), quantity > 0 )
RETURN
CALCULATE (
SUM( quantity ),
flag = 1,
title = "WEEKS"
) + IF( date > FirstDate, 0 )
If the condition is false, the IF returns a blank and it shouldn't show up.

Why does operator <= (less than or equal) not return expected result when date is variable?

Problem: DAX is not returning expected result in if statement with operator when date is a variable.
Background: I've checked to make sure that there is no date or time difference.
Dates are ALL in format (1stday of month, 12:00:00AM). I have 2 years (2018 & 2019: 24 distinct dates).
I've tried to use the <= operator in a calculated column to determine if a date is "Before/Same" to a variable date or "After". I've tried to combine < filter and = filter with || (or), same result.
TestColumn =
var CurrentDate = [Current_Period]
return
IF(
ValuesTable[Month-Year] <= CurrentDate,
"Before/Same", "After"
)
FYI: The [Current_Period] Measure, this works fine, returns one date as expected
Current_Period =
VAR ThisActMonth =
CALCULATE (
DISTINCT ( Fact_FX[Month-Year] ),
Fact_FX[bool_Latest_FX_Act] = TRUE ()
)
RETURN
ThisActMonth
I would expect that for every row where the Month-Year (Date) <= the result would be "Before/Same";
however, The result I currently get is:
"Before/Same" only where ValuesTable[Month-Year] = CurrentDate
CurrentDate = April 2019
"After" all other Months (23)
Please Help!
What's happening is that you are evaluating your Current_Period measure within the row context of the calculated column, so the measure doesn't see the row with Fact_FX[bool_Latest_FX_Act] = TRUE () except in the April row.
The solution is to calculate the Current_Period outside of that evaluation context and there are multiple possible approaches. A quick solution would be to remove row context using the ALL function inside of your CALCULATE:
Current_Period =
VAR ThisActMonth =
CALCULATE (
DISTINCT ( Fact_FX[Month-Year] ),
ALL( Fact_FX ),
Fact_FX[bool_Latest_FX_Act] = TRUE ()
)
RETURN
ThisActMonth

PowerBI Getting ERROR A function 'CALCULATE' has been used

I would like to show the card values:
if current month value is not available then it should compare with the previous month value automatically.
Like
In above image Apr-2017 value is not available then it should compare with the Mar-2017 value.
If Mar-2017 value also not available then the previous month value.Keep on goes.
And one more thing is I don't want to use the slicer anymore. Actually I am not going to use the slicer.
I just want to show the month comparison value in a card visuals.
I would like to give info of what kind of data that I have. I have table's plan rev, actual rev, and MonthYear
I have created a relationship using Date column from MonthYear table to plan rev and actual rev Date columns.
MonthYear table
And in plan rev, month year, plan rev, date, and in actual rev actual rev, month year, and date columns.
Then written measures for
For Sumof Plan rev-->
PlanSum = SUM('Revenue Report'[Planned Rev])
For Prev month value-->
PlanPrevMon = CALCULATE([PlanSum],PREVIOUSMONTH('Month Year'[Date]))
For Start and End Date of the months
FILTERDATESTART= FIRSTDATE('MonthYear'[Date])
FILTERDATEEND= LASTDATE('MonthYear'[Date])
Then for current month PlanArrows measure is.
PlanArrows = CALCULATE(
IF(
ISBLANK([PlanSum]),"No data Available",[PlanSum]
)& " "& IF(
[PlanSum]=[PlanPrevMon],
"",
IF([PlanSum]>[PlanPrevMon],
UNICHAR(8679),
UNICHAR(8681)
) & IF([PlanSum]<=0,
"",""
)
),
'Month Year'[Date]>=FILTERDATESTART,
'Month Year'[Date]<=FILTERDATEEND
)
But it is not working. I'm getting an error:
A function 'CALCULATE' has been used in a True/False expression that is used as a table filter expression. This is not allowed.
Any Suggestions please,
Thanks
Mohan V
I think i got the solution on my own.
I have written measure which solved this issue.
PlanArrows =
VAR s = [FILTERDATESTART]
VAR e = [FILTERDATEEND]
RETURN
CALCULATE (
IF ( ISBLANK ( [PlanSum] ), "No data Available", [PlanSum] ) & " "
& IF (
[PlanSum] = [PlanPrevMon],
"",
IF ( [PlanSum] > [PlanPrevMon], UNICHAR(8679), UNICHAR(8681) )
& IF ( [PlanSum] <= 0, "", "" )
),
'Month Year'[Date] >= s
&& 'Month Year'[Date] <= e
)