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

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:

Related

Power BI LOOKUPVALUE with a column of values for the search items? (VLOOKUP alternative)

In Power BI, I need to create a VLOOKUP alternative. From the research I've done, this is done with the LOOKUPVALUE function, but the problem is that function needs one specific SEARCH ITEM, which isn't super helpful in a VLOOKUP type scenario where you have a full column of values to search for?
Given these two tables, connected through the user_name and first_name columns:
...what's the formula needed in order to create a new column in the Employee_Table called phone_call_group by using the names as the search items in order to return the group they belong to? So how can I end up with this?
(Forget that the entries in each table are already sorted, needs to be dynamic). Will be back tomorrow to review solutions.
In Power BI you have relations between tables instead of Excel's VLOOKUP function.
In your case you just have to create a one-to-one relation between
'Phone_Call_Table'[user_name] and 'Employee_Table'['first_name]'
With that you can add a Calculated Column to your 'Employee_Table' using the following expression:
phone_call_group = RELATED(Phone_Call_Table[group])
and in the data view the table will look like this:
LOOKUPVALUE() is just a workaround if for other reasons you can't establish that relation. What you've been missing so far is that in a Calculated Column there is a Row Context which gives you exactly one value per row for the <search_value> (this is different from Measures):
alt_phone_call_group =
LOOKUPVALUE(
Phone_Call_Table[group],
Phone_Call_Table[user_name],
Employee_Table[first_name]
)

Treatas DAX function not working as expected, It is returning complete blank column

I trying to understand Treatas DAX function. There are two tables Assets and Ticket. Ticket table has parent and child relationship. For each value of Asset[AssetKey], I want to calculate count of childs in Ticket table. There is two relationships between these tables. One active and one inactive.
The Problem: When I use Treatas function complete measure Number of Child is retured blank. I used the formula -
Number of Child = CALCULATE(COUNT(Tickets[AssetKey]),TREATAS(SUMMARIZE(Asset,Asset[AssetKey]),Tickets[ParentId]))
To replicate the scenario follow the below steps:
Step 1: create table Asset:
Asset = DATATABLE("AssetKey",INTEGER,"Name",STRING,{{1,"Australia"},
{2,"Belgium"},
{3,"Canada"},
{4,"Denmark"},
{5,"England"}})
Create table Ticket
Tickets = DATATABLE("AssetKey",INTEGER,"ParentId",INTEGER,"TicketKey",INTEGER,{{3,1,1},
{1,Blank(),1},
{3,1,3},
{2,Blank(),4},
{4,2,5},
{3,1,6},
{2,Blank(),7},
{4,2,8},
{1,Blank(),9},
{5,2,10}})
Step2 : create relationship between Assets and Ticket table(one to many) on column AssetKey.
Step3: Now create the below Measures -
Number Of Tickets = COUNT(Tickets[TicketKey])
Number of Child = CALCULATE(COUNT(Tickets[AssetKey]),TREATAS(SUMMARIZE(Asset,Asset[AssetKey]),Tickets[ParentId]))
Now the problem: Why the Number of Child column comes out to be blank.
The expected output is :
Your problem is not the TREATAS but the SUMMARIZE. TREATAS expects table input so you summarized.
Try the following:
summarizedAsset = SUMMARIZE(Asset,Asset[AssetKey])
This returns you 1,2,3,4,5. Logic because this is what you asked it to do. Now TREATAS is going to do the same on the table Ticket. So it returns a table with one column values "empty",1,2. Exactly what we can expect.
Next thing you do a COUNT on AssetKey, this table just created does not have this column so it returns empty.
What you are looking for is a column what is calculating the children:
Number of Child =
var Akey = Asset[AssetKey]
return CALCULATE(COUNT(Tickets[ParentId]), filter(Tickets, Akey = Tickets[ParentId]))
This returns exactly what you where looking for.
PS: 10 points, you did an excellent job on the question asking, easy for others to reproduce. You work as a pro!!

Power BI - Creating a calculated table

I am creating a dashboard in Power BI. I have to report the executions of a process in a daily basis. When selecting one of these days, I want to create another calculated table based on the day selected (providing concrete information about the number of executions and hours) as it follows:
TABLE_B = FILTER(TABLE_A; TABLE_A[EXEC_DATE] = [dateSelected])
When [dateSelected] is previously calculated from the selected day as it follows:
dateSelected = FORMAT(FIRSTDATE(TABLE_A[EXEC_DATE]);"dd/MM/yyyy")
I tried a lot of alternatives as, for example, create individualy the year, month and day to later compare. I used the format in both sides of the comparation, but none of them works for me. The most of the cases it returns me the whole source table without any kind of filters. In other cases, it doesn't return anything. But, when I put a concrete day ...
TABLE_B = FILTER(TABLE_A; TABLE_A[EXEC_DATE] = "20/02/2019")
... it makes the filter correctly generating the table as I want.
Does someone know how to implement the functionality I am searching for?
Thanks in advance.
You're almost there Juan. You simply need to use dateSelected as a varialbe inside of your DAX query:
TABLE_B =
var dateSelected = FIRSTDATE(TABLE_A[EXEC_DATE])
return
FILTER(TABLE_A, TABLE_A[EXEC_DATE] = dateSelected)
Note that all my dates are formatted as Date so I didn't need to use a FORMAT function.
Here's the final result:
I admit that this behavior can be quite confusing! Here is a useful link that will help you understand Power BI's context:
https://community.powerbi.com/t5/Desktop/Filtering-table-by-measures/td-p/131361
Let's treat option 1 as FILTER(TABLE_A; TABLE_A[EXEC_DATE] = "20/02/2019") and option 2 as FILTER(TABLE_A; TABLE_A[EXEC_DATE] = [dateSelected]). Quote from the post:
In option 1, in the filter function, you are iterating
over each row of your 'Table' (row context). In option 2, because you
are using a measure as part of the filter condition, this row context
is transformed into an equivalent filter context (context transition).
Using variables (...) is very convenient when you want to filter
a column based on the value of a measure but you don't want context
transition to apply.

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

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

How can I ouput the values of a column (values() function) as a list in DAX for Power BI?

I use Power BI to create reports and visuals for large enterprise clients.
I have an interesting request from one of my clients: they would like to be able to see a summary of all filters that are applied to a given report. I used the ISFILTERED() function to create a card visual that lists the dimensions that are filtered, but they would like to be able to see which values are being shown. This works just fine when they have sliced or filtered for just one value, but how can I show when more than one is selected? My DAX is below:
Applied Filters =
var myvalues = VALUES(mytable[dimension_column])
return
IF(ISFILTERED(mytable[dimension_column]) = FALSE(),
"Not filtered",
"Column Name:" & UNICHAR(10) & mylist)
When only one value is selected in the slicer, the output is:
Column Name:
Selected Value
Obviously, when more than one value is selected in the slicer, variable mylist will have more than one value and the function fails. My question is, how can I convert the column myvalue to a list in DAX, so I can output each and every value?
What I want to get is:
Column Name:
Selected Value1,
Selected Value2,
etc.
Thank you!
One possibility is to concatenate all the values into a single string.
For example, you'd replace mylist with the string
CONCATENATEX(VALUES(mytable[dimension_column]), mytable[dimension_column], UNICHAR(10))
You're really only returning a single value for the measure, but it looks like a column.
Another approach is, instead of using a card, to simply create a table visual that just has mytable[dimension_column] for the values. This table will automatically filter as you adust slicers.