DAX syntax - Countrows using allexcept filter - powerbi

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.

Related

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

RANKX does not give the correct result

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
)

Using TREATAS to get Measure from Another Table

I'm back with another issue. I have a sales table with transaction details on the products purchased. I also have a table with warehouse inventory information for each product. I'm trying to get the count of products purchased in a Table visualization with columns from the warehouse inventory table.
I tried both of the measures below, but they both return the total Count for each row rather than sliced by product. Any help would be greatly appreciated!
NumProductsfromSales1 = calculate([Count], treatas(values('Sales'[Product]), 'Inventory'[Product]))
NumProductsfromSales2 =
var lineage = treatas(values('Sales'[Product]), 'Inventory'[Product])
var tbl = calculatetable('Inventory Detail', KEEPFILTERS(lineage))
var result = calculate(sumx(tbl, [Count]))
return result
From this source, we see TREATAS works as follows.
[Filtered Measure] :=
CALCULATE (
<target_measure>,
TREATAS (
VALUES ( <lookup_granularity_column> ),
<target_granularity_column>
)
)
is equivalent to
[Filtered Measure] :=
CALCULATE (
<target_measure>,
INTERSECT (
ALL ( <target_granularity_column> ),
VALUES ( <lookup_granularity_column> )
)
)
The important part is the ALL function. That's why you're losing the filter context from the rows in the visual.
I'm not sure if this is the most efficient solution, but I think if you add Inventory as a filter table to your first attempt, it should maintain the filter context on that table from the row in the visual.
NumProductsfromSales1 =
CALCULATE (
[Count],
'Inventory',
TREATAS ( VALUES ( 'Sales'[Product] ), 'Inventory'[Product] )
)
Edit: Regarding your comment, try the following:
a =
VAR top5prod =
SELECTCOLUMNS (
TOPN (
5,
SUMMARIZE ( Sales, Sales[Product], "Count", [Product Count] ),
[Count]
),
"Product", Sales[Product]
)
RETURN
CALCULATE (
[Product Count],
FILTER ( 'Inventory', 'Inventory'[Product] IN top5prod )
)
Using FILTER isn't as efficient as TREATAS but see if it works.
It's very difficult to answer this sort of question without having anything reproducible to work with.

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"
)