RANKX does not give the correct result - powerbi

I need to create a measure (not column) that would rank users based on value.
Here I am trying to use RANKX function:
ranking =
RANKX(
ADDCOLUMNS(
SUMMARIZE(dim_User,
dim_User[UserID],
dim_User[FirstName]
),
"Ttl Trans", [Ttl Transactions]
)
, [Ttl Transactions]
)
Same result using:
rating2 =
RANKX(
SUMMARIZE(dim_User,
dim_User[FirstName]
), [Ttl Transactions]
)
Tried this way:
rating1 =
RANKX(
SUMMARIZE(dim_User,
dim_User[FirstName],
"Trans",[Ttl Transactions]
), [Trans]
)
But gives me an error:
The value for 'Trans' cannot be determined. Either the column doesn't exist, or there is no current row for this column.
I also tried using COUNTROWS() function, but also no success.
It seems like it works if I use a table, not a table expression.
What am I missing here?
UPDATE:
Adding ALL(dim_User) still giving me 1
ranking =
RANKX(
ADDCOLUMNS(
SUMMARIZE(ALL(dim_User),
dim_User[UserID],
dim_User[FirstName]
),
"Ttl Trans", [Ttl Transactions]
)
, [Ttl Transactions]
)
UPDATE
No matter what user I select, in a rating in a card is always 1.

When you write a measure, it is evaluated within its local filter context. In particular, dim_User is filtered by FirstName within your measure and is, therefore, ranking Ttl Trans only compared to other users with the same FirstName.
Since you are ranking based on user, you want to remove the filter context introduced by the visual in order to get the ranking you expect. I'd suggest replacing the table argument dim_User with ALL(dim_User) to remove all filtering on that table or -- more likely the option you want -- with ALLSELECTED(dim_User) to remove the local filter context introduced by the visual while maintaining any filter context from slicers or page-level filters.
For your card, you'll need to simulate the filter context that exists in the table:
UserRanking =
VAR SelectedUser = SELECTEDVALUE ( dim_User[Name_FirstLast] )
RETURN
CALCULATE (
RANKX ( ALL ( dim_User ), [Ttl Transactions] ),
dim_User[Name_FirstLast] = SelectedUser
)

Related

DAX syntax - Countrows using allexcept filter

I am using three different measures in the same visual (clustered column chart), but in one of the measures I want to leave out the filter which is used in the other measures. That's why I can't use filter on visual because in one of the measures I don't want this to be used.
I am counting rows, a specific number in 'x_channel' column, but I only want to count rows that 'does not contain "3-"' from column "associate.name" in the same table (TICKET).
How do I add this filter in the following syntax:
E-post = CALCULATE(COUNTROWS(TICKET), TICKET[x_channel]=2, USERELATIONSHIP(DIM_DATO[Opprettet], TICKET[Created]))
I think the syntax should be something like this:
E-post = CALCULATE(COUNTROWS(TICKET), TICKET[x_channel]=2 && ALLEXCEPT(TICKET, TICKET[ASSOCIATE.name]="3-"), USERELATIONSHIP(DIM_DATO[Opprettet], TICKET[Created]))
Thank you!
Usage of ALLEXCEPT is totally different. According to the docs and dax.guide
ALLEXCEPT - Returns all the rows in a table except for those rows that are affected by the specified column filters.
So with this function, you can manipulate filter context to remove all filters from the given table but still keep filters from the column provided to ALLEXCEPT function.
The syntax would be like
Measure =
CALCULATE(
COUNTROWS( TABLE1 ),
ALLEXCEPT( TABLE2, TABLE2[ColumnName] )
)
For your case, try this one:
E-post =
CALCULATE(
COUNTROWS( TICKET ),
TICKET[x_channel] = 2,
TICKET[ASSOCIATE.name] <> "3-",
USERELATIONSHIP( DIM_DATO[Opprettet], TICKET[Created] )
)
or you can use FILTER with ALL and then COUNTROWS as follows
E-post =
CALCULATE(
COUNTROWS(,
FILTER(
ALL( TICKET ),
TICKET[x_channel] = 2 && TICKET[ASSOCIATE.name] <> "3-"
)
),
USERELATIONSHIP( DIM_DATO[Opprettet], TICKET[Created] )
)
In fact, the FILTER with ALL is used under the hood in the first scenario.

Remove visual filter context on dates but keep slicer filters on

I have two tables like this
I am trying to get NAV of the first date (in the selected dates). I tried multiple ways but couldn't get it. Here are a couple of expressions I tried. Any help would be greatly appreciated.
NAV First Date = CALCULATE(MIN(FundNAV[NAV]),ALLEXCEPT(FundNAV,FundNAV[Fund Name]),FIRSTDATE(Dates[Date]))
NAV First Date = CALCULATE(MIN(FundNAV[NAV]),FILTER(ALL(Dates[Date]),Dates[Date]=MIN(Dates[Date])))
I got it working with the below measure, but have a bug in the expression. As you can see for the third fund there is no record on the selected first date, so it's returning blank, ideally, it should return the next available NAV for all remaining days.
NAV First Date = VAR frist_date = CALCULATE ( FIRSTDATE( Dates[Date] ),ALLSELECTED(FundNAV),VALUES(FundNAV[Fund Name]))
RETURN CALCULATE(MIN(FundNAV[NAV]),Dates[Date]=frist_date)
Try this:
NAV First Date =
VAR mindate =
CALCULATE ( MIN ( FundNAV[NAV Date] ), ALLSELECTED ( Dates[Date] ) )
RETURN
CALCULATE ( MIN ( FundNAV[NAV] ), ALL(FundNAV[NAV Date]), FundNAV[NAV Date] = mindate )
This measure first calculated the minimum FundNAV[NAV Date], within the selected dates from the Dates tabel. Then it returns the FundNAV[NAV] for that date.
Please test below 2 measures. I think Both will solve your problems:
NAV First Date =
CALCULATE ( MIN ( FundNAV[NAV] ), ALL ( FundNAV[Fund Name]), ALL ( Dates[Date] ) )
and This one uses the entire fact table as filter. (Expanded tables logic. it also removes any filter on dates)
NAV First Date =
CALCULATE ( MIN ( FundNAV[NAV] ), ALL ( FundNAV ) )

DAX - ALLEXCEPT vs ALL+VALUES

In this video:
https://youtu.be/teYwjHkCEm0
It is said that ALLEXCEPT is not the same as ALL and VALUES. Further he says that - for filter context having CountryRegion, it makes no difference. But if there was a filter on Continent then the both are not equivalent. What exactly is happening in case of Continent?
When the only existing filter is on Customer[Continent] then the
ALLEXCEPT( Customer, Customer[CountryRegion] )
simply removes all the existing filters from the Customers table.
The
ALL( Customer ),
VALUES( Customer[CountryRegion] )
first saves the VALUES( Customer[CountryRegion] ), that are in the subset of Customer table resulting from the filter on Continent (that's to say the CountryRegions of the currently selected continents), then ALL( Customer ) filter modifier removes the existing filter on the whole Customer table and after that the VALUES( Customer[CountryRegion] ) filter that was evaluated before is applied. The result is that the CountryRegion is "Cross-filered" by the Continent.
this is also explained in this article Using ALLEXCEPT Versus ALL and-VALUES

DAX ALLEXCEPT to sum by category of multiple dimension tables

I would like to calculate total by category. The category is in the dimension table.
Here is sample file:
DAX ALLEXCEPT total by category.pbix
I have the following model:
These are my expected results. Total by Color:
I thought I could achieve expected results by the following measure:
ALLEXCEPT_color =
CALCULATE (
[Sales],
ALLEXCEPT (
FactTable, -- surprisingly 'dim1' table in that place gives wrong results
dim1[Color]
)
)
Or alternatively using method suggested by Alberto Ferrari https://www.sqlbi.com/articles/using-allexcept-versus-all-and-values/:
ALL_VALUES_color =
CALCULATE (
[Sales],
ALL (FactTable), -- again, 'dim1' produces wrong results, has to be FactTable
VALUES ( dim1[Color] )
)
Both these measures work and return proper results. However they multiply displayed results making Cartesian product of all the dimensions. Why? How to prevent it?
I achieve expected results with measure:
Expected_Results_Color =
IF (
ISBLANK ( [Sales] ),
BLANK (),
[ALLEXCEPT_color]
)
Probably I am missing something about ALLEXCEPT function so I do not get what I want for the first shot. What is the logic behind using ALLEXCEPT function with multiple tables, especially with far off dimensions, away from the center of star schema.
What pattern to use? Here I found promising solution which looks like this:
ByCategories =
CALCULATE (
SUM ( FactTable[Sales] ),
ALLEXCEPT (
dim1,
dim1[Color]
),
ALLEXCEPT (
dim2,
dim2[Size]
),
ALLEXCEPT (
dim3,
dim3[Scent]
)
)
But as I tested it before it does not work. It does not aggregate [Sales] by dimensions but produces [Sales] as they are.
So I found out that this is the correct direction:
ByCategories =
CALCULATE (
SUM ( FactTable[Sales] ),
ALLEXCEPT (
FactTable, -- here be difference
dim1[Color],
dim2[Size],
dim3[Scent]
)
)
I speculate there might be also another way.
Measure =
var MyTableVariable =
ADDCOLUMNS (
VALUES ( dim1[color] ),
"GroupedSales", [Sales]
)
RETURN
...
If only we could retrieve single scalar value of GroupedSales from MyTableVariable and match it with appropriate color in table visual.
I would be very grateful for any further insights in calculating total for category.
This is expected behaviour.
Power BI tables will include every row for which any measure in the table does not evaluate to BLANK().
ALLEXCEPT stops the values in the id and size columns from affecting the filter context when [Sales] is computed, and so every possible value for these two columns will give the same (non-blank) result (this causes the cartesian product that you see).
For example, on the (a, black, big) row, the filter context for the measures contains:
FactTable[id] = {"a"}
dim1[color] = {"black"}
dim2[size] = {"big"}
Then CALCULATE([Sales], ALLEXCEPT(...)) removes the FactTable[id] and dim2[size] from the filter context when evaluating [Sales]; so the new filter context is just:
dim1[color] = {"black"}
[Sales] in this filter context is not BLANK(), so the row is included in the result.
The proper way to fix this is to wrap the result in an IF, as you do in your Expected_Results_Color measure, or to add a filter on [Sales] not Blank to the table in Power BI.

Using summarize and userelationship to generate a sum based on a condition

Story:
I have two date columns in my fact table, one is for orderdate and the second is for orderdate/refund/cancelled date.
I created two relationships between the date table and the fact table.
Active: Date > OrderDate
Inactive: Date > OtherDate
I would like to sum the # of refunds per day using the inactive relationship.
What I tried:
Returns =
VAR summary =
SUMMARIZE (
FILTER ( Query1, Query1[kind] = "refund" ),
Query1[orderId],
"returns", MAX ( Query1[amount] )
)
RETURN
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
summary
)
For some reason, it's using the active date column. Any suggestion on how to fix the above formula?
I'm not sure I understand how you are intending to use the summary variable here, but note that USERELATIONSHIP doesn't affect it at all since it's already computed.
You might not need that variable at all. Try this:
Returns =
CALCULATE (
MAX ( Query1[amount] ),
USERELATIONSHIP ( Query1[OtherDate], DateTable[Date] ),
Query1[kind] = "refund"
)