Display Matched and Non Matched Values based on a slicer value Power BI - powerbi

I am working on a Viewership table which tells which customer watches which asset. Based on the asset filter, I need to display the customers who watched the show & customers who didn't watched the show. below is my example table
If the asset_id selected as 1 in the slicer, the desired output will be as below
I have tried creating a cross-join table with asset_id and customer_id , but that approach taking much time with large data. Request the experts here to suggest the best optimal solution to achieve this.

First, create a new table "Asset":
This table contains unique assets, and we will use it to create a slicer that affects DAX measure but does not affect the visual (table). To achieve that, the Asset table must be disconnected from the Viewership table (no relationships).
In your viewership table, I just renamed "asset" to "asset_id", to be consistent:
Next, create a measure:
Status =
VAR Selected_Asset = SELECTEDVALUE(Asset[asset_id])
VAR Customer_Asset = SELECTEDVALUE(Viewership[asset_id])
RETURN
IF(Customer_Asset = Selected_Asset, "Watched", "Not Watched")
Result:
Slicer here is created from the "Asset" table, and table is a table visual with customer_id and asset_id from the Viewership table (set them as "don't summarize" values). I turned off "total", assuming you don't need it.
This design requires to set Asset slicer to "single selection" mode, to make sure that you are only getting one value from it. If you want the model to work with multi-select slicer, change DAX measure as follows:
Multi Status =
VAR Selected_Assets = ALLSELECTED(Asset[asset_id])
VAR Customer_Asset = SELECTEDVALUE(Viewership[asset_id])
RETURN
IF(Customer_Asset IN Selected_Assets, "Watched", "Not Watched")
Result:
Edit:
To make it work at the customer level:
Customer Status =
VAR Selected_Assets = ALLSELECTED(Asset[asset_id])
VAR Customer_Assets = VALUES(Viewership[asset_id])
VAR Assets_Watched = COUNTROWS(INTERSECT(Customer_Assets, Selected_Assets))
RETURN
IF(Assets_Watched > 0, "Watched", "Not Watched")
Result:
Explanation: store selected assets in a table variable. Then, store assets visible per customer in another table variable. Find an intersect of the two tables (what they have in common), and count intersect rows. If none - not watched, otherwise watched. If you want, you can actually display the number of movies watched (just return "Assets_Watched" instead of IF statement).

Related

Power BI Dax Measure and return multiple columns

I am filtering the data based on the current logged in user using the below query, now I would like to return some of the columns associated with that user - how to achieve that ?
In the below case I get only 1 value - I tried to return a complete row but it throws me the error "Multiple columns cannot be converted to a scalar value" - any other way to show multiple columns?
CurrentUserData =
VAR CurrentUserState = CALCULATE(MAX(TimeReport[UserPrincipalName]),FILTER(TimeReport, TimeReport[UserPrincipalName] = USERPRINCIPALNAME()))
RETURN
IF(
SELECTEDVALUE(TimeReport[UserPrincipalName]) = CurrentUserState,
Values(TimeReport[Neukunden_Akquise_Produkte])
)
Reference: https://community.powerbi.com/t5/Desktop/Show-Current-Logged-in-User-data-only/m-p/2219446#M810376
Thanks
Got the solution and credit goes to #miguelarce
https://community.powerbi.com/t5/Developer/RLS-vs-Filter-for-current-user/m-p/329584
Measure1
WhoIsWatching = USERPRINCIPALNAME()
(that is email style usernames, or you can use USERNAME() for windows style users)
Measure 2
FilterByViewer = IF(selectedvalue(table[email])=[WhoIsWatching],1,0)
Drag Measure 2 as a filter for visual, select advanced filtering and set it to
"Show items when value IS 1"

Display Count of Users based on Multiple slicer values Power BI

I am working on a Viewership table which tells numbers of customers watches asset. There are two asset filters. One for watched and one for not Watched. Based on the asset filters, I need to display number of customers who watched the show & customers who didn't watched the show. Below is the method I have used.
First, created a new table "Asset":
This table contains unique assets and used it to create a slicers that affects DAX measure but does not affect the visual (table). Asset table disconnected from the Viewership table (no relationships).
Created the copy of the above table for not watched assets and named it as asset_1
below is the viewership table.
Created below measures to get the customers who viewed the selected asset (from first slicer) & he customers who not viewed the selected asset (from second slicer) &
Watched Status =
VAR Selected_Assets = ALLSELECTED(Asset[asset_id])
VAR Customer_Assets = VALUES(Viewership[asset_id])
VAR Assets_Watched = COUNTROWS(INTERSECT(Customer_Assets, Selected_Assets))
RETURN
IF(Assets_Watched > 0, "Watched", "Not Watched")
Not Watched Status =
VAR Selected_Assets = ALLSELECTED(Asset_1[asset_id])
VAR Customer_Assets = VALUES(Viewership[asset_id])
VAR Assets_Watched = COUNTROWS(INTERSECT(Customer_Assets, Selected_Assets))
RETURN
IF(Assets_Watched > 0, "Watched", "Not Watched")
I got below result
after applying below filters in the visual filter pane I can see the desired result.
Watched Status= "Watched",
Not Watched Status = "Not Watched"
Now I got a Requirement to show total number of customers (Instead list of customers) with above filter criteria. For e.g: In the above case customer count is 1.
I have tried below measure.
Customer Count = CALCULATE(DISTINCTCOUNT(Viewership[customer_id]),FILTER(Viewership,([Watched Status]= "Watched") &&left([Not Watched Status],3)="Not"))
The expected result is 1 (Customer ID: 4). But I am getting result as 2. Could someone help to identify the issue here?
What you can do is drag teh customer_id in the visual as column and ensure it is set to count distinct.
Select your visual, go the the vusialization panel under values you can see the column, click on arrowdown, popus will show:

Filtering other tables based on cross-highlighting a filtered measure

I want to count records in a certain condition and allow people to filter down to the relevant records, but selecting a measure value (which filters so it only counts certain rows) isn't cross-filtering others as I'd expect. Maybe ths isn't possible or maybe I'm just doing it wrong, but I'd appreciate help.
I have a single table:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45Wci4tLsnPTS1SMFTSUTJUitVBEjICChmgChljCplgajSFCMUCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Customer Name" = _t, #"Ordered Recently" = _t]),
#"Change to INT" = Table.TransformColumnTypes(Source,{{"Ordered Recently", Int64.Type}}),
#"Change to T/F" = Table.TransformColumnTypes(#"Change to INT",{{"Ordered Recently", type logical}})
in
#"Change to T/F"
The result looks like this:
Customer Name Ordered Recently
Customer 1 True
Customer 2 False
Customer 3 False
Customer 4 True
Customer 5 True
I added two measures:
Count Total = COUNTROWS(Customers)
Count Recent = CALCULATE([Count Total], filter(Customers, Customers[Ordered Recently]))
If I put both measures in a bar chart and highlight the "Count Recent" measure, I'd expect it to know to filter other visuals based on the FILTER statement present in the measure, but that doesn't happen. Selecing this value doesn't impact anything else on my page (including just a count of rows).
The goal is to allow people to select a measure that counts rows and then to see the makeup of the data in those rows (select a count of late projects and filter other visuals to describe those late projects).
Is this possible or am I doing something wrong?
EXAMPLE:
Here's what it looks like now, with nothing selected:
When I select the black bar (the "Ordered Recently" measure), nothing changes right now - but here's what I want to happen (actually achieved with a slicer off screen on the T/F field):
I understand if my measure is a SUM of an integer field, it includes every row in the calculation - even when the row value is zero - and there's no way to filter my dataset based on that. However, in this case, my measure is actually using a FILTER on the dataset so that it only counts rows with a certain criteria set - given that, it should be able to filter the requested table, and then flow that filter through the rest of my dataset (the same way it would if I selected a bar from a chart where I had used that same field as the series - exactly how it works when I do this:
PBIX file to download as an example
No, I don't believe it's possible to make a measure value cross-filter other visuals based on filters within the measure definition.
You can, however, click on i.e. row header Customer 3 and it should cross-filter the other visuals to only include that customer. Any table column you set for the rows or columns of a matrix visual should behave this way.
Here's a hacky workaround:
Create a measure that shows the right values when you use the column you want to use as a filter as the Legend or Axis (like in your last image). For example, in this case, you could do this:
Total Customers =
VAR TF = SELECTEDVALUE ( Customers[Ordered Recently] )
RETURN
COUNTROWS (
FILTER (
ALLSELECTED ( Customers ),
IF ( TF, TF, TF || Customers[Ordered Recently] )
)
)
This behaves how you want, but isn't labeled as you want. To achieve that create a calculated column with the labels you want. For example,
Label = IF(Customers[Ordered Recently], "Ordered Recently", "Total Customers")
Then take Ordered Recently off the axis and put the Label column in the Legend box to get this:
Your Filter argument is really Filter(All(Customers, Customers[Ordered Recently])
You remove all filters on the Customer Table, and then specify Ordered Recently Column as the filter.
Try
[MeasureName] =Calculate([Count Total], All(Customer), Values(Customer[Recently Ordered]), Customer[Recently Ordered] = “True”)

How to Perform a Full-Outer Join on Two Separate, Filtered Tables using DAX?

I have an original table named Error, and two additional tables (ErrorBefore and ErrorAfter) derived from the original (e.g. ErrorAfter = ALLSELECTED('Error')). I want to compare values from a 'before' version with an 'after' version, with the different version picked by slicer with 'Single select' on. That's working okay. Now I want to perform a full-outer join on the two results, joining on the Message column. The image below shows the result I have so far, with a fabricated table at the bottom of what I'm trying to achieve. I've tried using NATURALLEFTOUTERJOIN and GENERATE but they either don't give the result that I seek. Does anyone know how to perform the join?
PBIX share here.
First, change your data model to this:
I removed all your derived tables and relations, and instead created 2 tables like this:
Version Before = DISTINCT('Error'[Version])
Version After = DISTINCT('Error'[Version])
Both tables should have no relations with the Error table.
Then, create a measure:
Message Count = COUNT('Error'[Message])
You should always create measures yourself, never use Power BI auto-aggregations.
Next, create a measure for "Before" count"
Message Count Before =
VAR Version_Before = SELECTEDVALUE('Version Before'[Version])
RETURN
CALCULATE([Message Count], 'Error'[Version] = Version_Before)
and, similarly:
Message Count After =
VAR Version_After = SELECTEDVALUE('Version After'[Version])
RETURN
CALCULATE([Message Count], 'Error'[Version] = Version_After)
Finally, adjust your visuals:
Slicer "Before" should be based on table "Version Before"
Slicer "After" should be based on table "Version After"
Charts and tables should use "Message Count Before" and "Message Count After" measures in values
Add another table with messages and both measures
Result:

Obtain MAX of column and display for each row

I'm trying to obtain the MAX of a particular column in a Power BI Report and place this as a new Measure within each ROW of the same dataset. Please see the example below.
Is this possible in DAX and via DirectQuery/LiveConnection? The report is pointing to a tabular model but due to outside factors the measure must be created in the report.
Thanks
You can accomplish this a few ways. Essentially, you need override the filter context so that the MAX function isn't just running over whatever slice you're showing in the visual. Using CALCULATE or the iterator function MAXX, set the wrap the table in the ALL() function to override the context and calculate max over all rows.
= CALCULATE(MAX([Calendar`Year]), ALL('Smithfield_Fiscal_Calendar'))
or
= MAXX(ALL('Smithfield_Fiscal_Calendar'), [Calendar`Year])
To get the breakout by date, you'll need to include a Date table in your model. PowerBI makes this possible with a few different DAX options. As an example, go to your Model tab, click 'New Table' and put in the following expression:
MyCalendar = CALENDAR(DATE(2019,1,1), DATE (2019,1,10))
This is a little trivial -- you'd want to use a useful range of dates but this one matches your example above. Next, add a column to [MyCalendar]
CalendarMonthYear = month([date]) & "-" & year([date])
Go to your budget table and add a similar field
BudgetMonthYear = month([date]) & "-" & year([date])
Go into your Model view and create a relationship between CalendarMonthYear and BudgetMonthYear. This will associate every date in the date table with the particular budget row from your budget table.
Hope it helps.