Short version of question: how can I create a rank based on a calculated measure?
Question background:
I have a table/query that yields many rows for each employee, with each row having a time taken value.
I'd like to calculate the average time taken for each employee, and then present a table with a row for each employee, showing their name, average time taken, and rank (based on time taken).
To do the first part, I created a measure called AverageTimeLength and set it equal to:
AverageTimeLength = Average(Table_name[Column_name])
Then I coded the following:
AverageTimeLength_employee = CALCULATE([AverageTimeLength], GROUPBY(Table_name, Table_name[EmployeeName]))
These two are measures; I was able to insert the second into the new table chart I'm creating, but unfortunately, I can't use RANKX() on it because the measure values don't come from a column. If I try to create a column derived from the measure (i.e., column_name = [AverageTimeLength_employee]) I just get an error accusing column_name of circular reasoning.
What I want to do seems like it should be simple; does anyone know how I can create a simple rank parameter, to rank the measure values?
You can create the Average measure and use it in the Rank measure as follows:
Average = AVERAGE([Time taken])
Rank = IF (
HASONEVALUE ( Table_Name[Name] ),
RANKX ( ALL ( Table_Name[Name] ), [Average])
)
Hope it helps.
Related
I have some Fact Revenue, I am trying to group by Conca, and display the values only if negative…
For doing it I have this calculated column:
=
VAR name1 = Revenue[Conca]
VAR name2=
CALCULATE (
SUM ( Revenue[CostOfQuality] ),
FILTER ( Revenue, Revenue[Conca] = name1 )
)
RETURN
if (name2>0, 0, Revenue[CostOfQuality])
It works:
(highest value is 0 as expected):
Now...
If I drag fiscal year it stops working:
Why is it that I see numbers higher than 0?? (I want it to still work even if I bring other filters...)
a calculated column is computed computed once on the whole dataset after the data are loaded, and is basically a "static column".
Whatever the expected result, you are looking for a measure, which gets computed in the current context
Calculated columns and calculated tables are different from measures, since they are static: You can filter them, but they don't recalculate on filter changes.
My intention is to populate days of the month to simulate a data warehouse periodic snapshot table using DAX measures. My goal is to show non-additive values for the quantity.
Consider the following transactions:
The granularity of my snapshot table is day. So it should show the following:
Take note that a day may have multiple entries but I am only interested in the latest entry for the day. If I am looking at the figures using a week period it should show the latest entry for the week. It all depends on the context fixter.
However after applying the measure I end up with:
There are three transactions. Two on day 2 and the other on day 4. Instead of calculating a running total I want to show the latest Qty for the days which have no transactions without running accumulating totals. So, day 4 should show 4 instead of summing up day 3 and day 4 which gives me 10. I've been experimenting with LASTNONBLANK without much success.
This is the measure I'm using:
Snapshot =
CALCULATE(
SUM('Inventory'[Quantity]),
FILTER(
ALL ( 'Date'[Date] ),
'Date'[Date] <= MAX( 'Date'[Date] )
)
)
There are two tables involved:
Table # 1: Inventory table containing the transactions. It includes the product id, the date/time the transaction was recorded and the quantity.
Table # 2: A date table 'Date' which has been marked as a date table in Power BI. There is a relationship between the Inventory and the Date table based on a date key. So, in the measure, 'Date'[Date] refers to the Date column in the Date table.
You can use the LASTNONBLANKVALUE function, that returns the last value of the expression specified as second parameter sorted by the column specified as first parameter.
Since LASTNONBLANKVALUE implicitly wraps the second parameter into a CALCULATE, a context transition happens and therefore the row context is transformed into the corresponding filter context. So we also need to use VALUES to apply the filter context to the T[Qty] column. The returned table is a single row column and DAX can automatically convert a single column, single row table to a scalar value.
Then, since we don't have a dimension table we have to get rid of cross-filtering, therefore we must use REMOVEFILTERS over the whole table.
the filter expression T[Day] < MaxDay is needed because LASTNONBLANKVALUE must be called in a filter context containing all the rows preceding and including the current one.
So, assuming that the table name is T with fields Day and Qty like in your sample data, this code should work
Edit: changed in order to support multiple rows with same day, assuming the desired result is the sum of the last day quantities
Measure =
VAR MaxDay =
MAX ( T[Day] )
RETURN
CALCULATE (
LASTNONBLANKVALUE (
T[Day],
SUM ( T[Qty] )
),
T[Day] <= MaxDay,
REMOVEFILTERS ( T )
) + 0
Edit: after reading the comments, this might work on your model (untested)
Measure =
VAR MaxDay =
MAX ( 'Date'[Date] )
RETURN
CALCULATE (
LASTNONBLANKVALUE (
Inventory[RecordedDate],
SUM ( Inventory[Quantity] )
),
'Date'[Date] <= MaxDay
) + 0
I have a Table with a measure calculating difference of a KPI across a unique combination of three categories. I am trying to rank the measure that is calculating the difference but I get repetitive ranks although the value being ranked is different.
Table:
What I tried:
Rank Measure =
CALCULATE(
RANKX(
ALLSELECTED(Dim106),
[Difference between spend in region and store],,
DESC
)
)
[Difference between spend in region and store] = StoreTurnover - RegionTurnover.
RegionTurnover = CALCULATE(SUM(Dim106[Turnover |EJR|]),ALL(FactStore[Store ID]),ALL(FactStore[SOE]),ALL(FactStore[SOM]),ALLSELECTED(FactStore[Region]),ALLSELECTED(FactStore[YearMonth]),ALL(Dim106[WGI]),all(Dim106[Item Family]),ALL(Dim106[Item Subgroup]),ALL(Dim106[WGI Desc]),ALL(Dim106[Item Subgroup Desc]),ALL(Dim106[Item Family Desc]),ALL(Dim106[UniqueKey]))
StoreTurnover = CALCULATE(SUM(Dim106[Turnover |EJR|]),ALLSELECTED(FactStore[SOM]),ALLSELECTED(FactStore[SOE]),ALLSELECTED(FactStore[Store ID]),ALLSELECTED(FactStore[YearMonth]),ALLSELECTED(Dim106[Store]),ALLSELECTED(Dim106[Month]),ALL(Dim106[WGI]),ALL(Dim106[Item Subgroup]),ALL(Dim106[Item Family]),ALL(Dim106[WGI Desc]),ALL(Dim106[Item Subgroup Desc]),ALL(Dim106[Item Family Desc]),ALL(Dim106[UniqueKey]))
I have a fact table which has a higher hierarchy of store and and month, it has a crossfilter both directions relationship
Richt click on your dataset fields New Column and use the following expression:
Rank Column = RANKX('YourTable';'YourTable'[YourColumn];;ASC)
UPDATE:
Maybe this suits your scenario:
RankingBySale = Rankx(All(Table1[SalesID], Calculate(Sum(Table1[SalesValue])), , Asc, Dense)
I am trying to give rank to each row in daily stock price details table to figure out previous day closing price:
The code I use is:
rank =
RANKX(
FILTER(
ALL(NSE_DAILY_REPORT),
NSE_DAILY_REPORT[SYMBOL]="ADLABS"
),
MAX(NSE_DAILY_REPORT[TDATE]),,
ASC
)
The problem is that it returns a rank of 1 for all rows.
Try changing MAX(NSE_DAILY_REPORT[TDATE]) to NSE_DAILY_REPORT[SCLOSE]
The second argument expects an expression to compare to evaluations of that same expression in the filtered subset. Using MAX will yield that every record gets ranked in a set of just one record, hence the 1 for all rows.
So if I understand correctly your goal is to get the closing price of the day before?
In that case RANKX() is not necessary in contrast to the post you shared as an example. There they create ordinality by creating a ranking first and then perform a pretty inefficient calculation to get the previous in rank. There already is ordinality as you have a date column. Power BI already knows how to interpret that scale, so getting a value for a previous day does not need an additional ranking.
There's tons of posts around stack overflow dealing with this problem. Have a look around to learn more. For your particular problem, the solution will be a calculated column with code looking something like:
PreviousDay =
CALCULATE (
SUM ( NSE_DAILY_REPORT[SCLOSE] ),
FILTER (
ALLEXCEPT ( NSE_DAILY_REPORT, NSE_DAILY_REPORT[SYMBOL] ),
NSE_DAILY_REPORT[TDATE] = EARLIER(NSE_DAILY_REPORT[TDATE]) - 1
)
)
It will do the trick, but it still has some inefficiencies you can improve by looking through other examples like this
I have the simple dataset as below:
I need to permit summing the DistanceTraveled column in a "Measure" given date filters selected, and date order, to allow a cumulative total. The data model is dead simple as it only have one date dimension:
My DAX for the measure is:
Measure = CALCULATE(SUM(ActivityReport[DistanceTraveled]), FILTER(Timestamp,Timestamp[Timestamp] <= MAX(Timestamp[Timestamp])))
I know I must be missing something simple, how can I create a cumulative total given the filtered and increasing Timestamps for column DistanceTraveled?
I think you forgot to include all dates, Try this..
Measure = CALCULATE(
SUM(ActivityReport[DistanceTraveled]),
FILTER(ALL('Timestamp'[Timestamp]),
Timestamp[Timestamp] <= MAX(Timestamp[Timestamp])
)
)
What I ended up doing:
Measure = CALCULATE(
SUM(ActivityReport[DistanceTraveled]),
FILTER(ALLSELECTED(ActivityReport),
ActivityReport[Timestamp] <= MAX(ActivityReport[Timestamp])
)
)