Forum Discussion
DAX. Find value based on rankx
Ok, this is turning out to be quite a challenge for my scope of DAX. Here is the progress I've made so far.
To test the measures, I've opted for creating a filter date to see the physical rendering of each measure. This means there are some filter expressions in the measures simply to get rid of blank rows.
So here goes
First, the model (including a separate date table to limit the rows in the visual. For this exercize I'm looking at a 1 year range:
Now the measures step by step:
Sum Value = SUM(FactTable[Value])
Ascending rank for rows with negative values:
Rank -ves =
VAR _mindate =
CALCULATE (
MIN ( 'Date Sel'[Sel Date] ),
DATEADD ( 'Date Sel'[Sel Date], -1, YEAR )
)
VAR _DatesTable =
CALCULATETABLE (
ALLSELECTED ( 'Date Table'[Date] ),
DATESBETWEEN ( 'Date Table'[Date], _mindate + 1, MAX ( 'Date Sel'[Sel Date] ) )
)
VAR _Rows =
COUNTROWS (
CALCULATETABLE (
VALUES ( 'Date Table'[Date] ),
FILTER (
'Date Table',
'Date Table'[Date] > _mindate
&& 'Date Table'[Date] <= MAX ( 'Date Sel'[Sel Date] )
)
)
)
RETURN
IF (
AND ( _Rows >= 1, [Sum Value] < 0 ),
RANKX ( _DatesTable, [Sum Value],, ASC, DENSE )
)
Number of rows with negative values:
MAX _ve Rows =
MAXX(ALL('Date Table'[Date]), [Rank -ves])
Descending Rank of positive values
Rank +ves =
VAR _mindate =
CALCULATE (
MIN ( 'Date Sel'[Sel Date] ),
DATEADD ( 'Date Sel'[Sel Date], -1, YEAR )
)
VAR _DatesTable =
CALCULATETABLE (
ALLSELECTED ( 'Date Table'[Date] ),
DATESBETWEEN ( 'Date Table'[Date], _mindate + 1, MAX ( 'Date Sel'[Sel Date] ) )
)
VAR _Rows =
COUNTROWS (
CALCULATETABLE (
VALUES ( 'Date Table'[Date] ),
FILTER (
'Date Table',
'Date Table'[Date] > _mindate
&& 'Date Table'[Date] <= MAX ( 'Date Sel'[Sel Date] )
)
)
)
RETURN
IF (
AND ( _Rows >= 1, [Sum Value] > 0 ),
RANKX ( _DatesTable, [Sum Value],, DESC, DENSE ) + [MAX _ve Rows]
)
Final Rank of all rows by Item
All Rank Vals =
[Rank -ves] + [Rank +ves]
Median calculation
MEDIAN =
VAR _Table =
ADDCOLUMNS (
SUMMARIZE (
FILTER ( FactTable, NOT ( ISBLANK ( ( [All Rank Vals] ) ) ) ),
'Dim Item'[dItem],
'Date Table'[Date]
),
"@RANK", [All Rank Vals]
)
VAR _Median =
ROUND ( MEDIANX ( _Table, [@RANK] ), 0 )
RETURN
_Median
FInal Value based on Median:
Final Median Value =
VAR _FinalMed =
ROUND ( CALCULATE ( [MEDIAN], REMOVEFILTERS ( 'Date Table'[Date] ) ), 0 )
RETURN
AVERAGEX (
ALLSELECTED ( 'Date Table'[Date] ),
CALCULATE ( IF ( [All Rank Vals] = _FinalMed, [Sum Value] ) )
)
To get:
I've attached the sample PBIX file
Apologies for the delay, but as I say, it's quite a challenge. I'll keep at it, but can't promise anythig at this stage...
Thank you very much!
True, it is very very challenging 😄 As I see, ranking is correct, but need to set 3 years period for ranking.
However, I'm very happy to get some progression! At least something what could help me to move on 🙂
- PaulDBrown4 years ago
Community Champion
regarding the period, I just limitted to 1 year because it's easer to see what's going on.
For 3 years, just change the period reference. In fact, there is a cleaner code for the period calculation.
Use
VAR TESTDATES = DATESINPERIOD('Date Table'[Date], MAX('Date Table'[Date]), -3, YEAR)instead of the much more convoluted...
VAR _mindate = CALCULATE(MIN('Date Sel'[Sel Date]), DATEADD('Date Sel'[Sel Date], -1, YEAR)) VAR _DatesTable = CALCULATETABLE(ALLSELECTED('Date Table'[Date]), DATESBETWEEN('Date Table'[Date], _mindate+1, MAX('Date Sel'[Sel Date])))