How to find the sum of values present in one table and missing in other table - powerbi

I am trying to find the sum of the values corresponding to a key that is present in Table 1 but not in Table 2.
These tables have been created based on some filters and represent the values on 2 different dates.
The two different dates are chosen from 2 different date tables which have an inactive relationship, specially created for this purpose.
I want to create a measure that finds out the sum.
Below is the syntax I have used:
Difference =
VAR
Table1 = CALCULATETABLE(VALUES('TableA'[Id]), 'TableA'[Type] = "ABC", ALL('Date'), USERELATIONSHIP('Date'[As of Date], Previous_Date[Previous_Date]),USERELATIONSHIP('Date'[As of Date], 'TableA'[As of Date]))
VAR
Table2 = CALCULATETABLE(VALUES('TableA'[Id]), 'TableA'[Type] = "ABC", USERELATIONSHIP('Date'[As of Date], 'TableA'[As of Date]))
RETURN
IF(AND(VALUES('TableA'[Id]) IN Table1 , NOT(VALUES('TableA'[Id])) IN Table2),
CALCULATE(SUM('TableA'[Values])),0)
It is error-free. However, when I drop the measure on a KPI visual, I am getting the following message:
Please tell me what is wrong with the syntax. Also, please let me know if there is any better code that can be written.
Kindly help.

The reason you are getting an error is that it expects a single value for x when you write x IN Table1 but using the VALUES function can return a list rather than a single value.
I'd try something more like this after the RETURN:
SUMX (
'TableA',
IF ( 'TableA'[Id] IN Table1 && NOT ( 'TableA'[Id] IN Table2 ), 'TableA'[Value] )
)
This iterates through each row of TableA and checks if the Id value in each row is in the tables you calculated. If the condition is met, it adds the Value. Otherwise IF returns a blank (which is treated the same as 0 in a sum) since there is no third argument.

Related

Counting unique values in column A where all values in column B match condition?

Suppose I have data, in power bi, in the following form...
group
condition
A
yes
A
maybe
B
yes
B
yes
question
Is there a way to count the distinct elements of one column, where every value in another column matches a condition?
e.g. can we create a count of distinct group values where every associated [condition] equals yes?
Sure. Just use Distinctcount and put a filter on condition. You don't even need to write a measure; you can do it with the visual designer.
It needs more than just a small brain-storming, please try this measure as your DAX Code:
Your_Measure =
VAR TblSummary = ADDCOLUMNS(
VALUES(YourTbl[group]),
"DisCount",CALCULATE(DISTINCTCOUNT(YourTbl[group]),YourTbl[condition] = "yes"),
"Total Count",CALCULATE(COUNT(YourTbl[group]),YourTbl[condition] = "yes")
)
RETURN
SUMX(
FILTER(TblSummary,[DisCount] <> [Total Count]),[DisCount])
If we test it on a table visual, It returns:

DAX DEFINE returns column not found error

This works:
EVALUATE
ADDCOLUMNS(
FILTER (Sales, [StoreKey] = 155 ) ,
"Margin", (Sales[SalesAmount] - Sales[TotalCost])
)
However, if I try to define a function, I get an error:
DEFINE VAR Margin = Sales[SalesAmount] - Sales[TotalCost]
EVALUATE
ADDCOLUMNS(
FILTER (Sales, [StoreKey] = 155) ,
"Margin", Margin
)
Query (1, 21) A single value for column 'SalesAmount' in table 'Sales'
cannot be determined. This can happen when a measure formula refers to
a column that contains many values without specifying an aggregation
such as min, max, count, or sum to get a single result.
What is this error and how to fix it?
There are 2 problems with the second code:
It's missing Row Context
VAR is not a function, it's a variable. Functions in DAX are Measures
What is "Row Context"? In short, in Power BI data is stored in a database. When you are referring to a column in the database, you must either: aggregate the data in it (i.e., sum it), or provide a specific row ("row context").
In your first code, function ADDCOLUMNS is an iterator. It means that it loops a table row by row, and for each record does a calculation. Since during each iteration it "knows" which row it's on, you can refer to the table fields without problems.
In the second code, this line:
Margin = Sales[SalesAmount] - Sales[TotalCost]
has no row context - it does not know which record to use for the calculation, and hence the error. You must either aggregate the data first, or put this calculation inside an iterator.
In this particular case, the simplest solution is to use aggregation:
DEFINE
MEASURE 'Sales'Margin = SUM ( Sales[SalesAmount] ) - SUM ( Sales[TotalCost] )
EVALUATE
ADDCOLUMNS (
CALCULATETABLE ( Sales, Sales[StoreKey] = 155 ),
"Margin", [Margin]
)
Here, we first aggregate amounts and costs and calculate margin. Then, inside of ADDCOLUMNS we iterate table Sales filtered for a specific store, and for each row we call the measure defined above.
If you need to use an iterator instead of aggregation, you can do something like this:
DEFINE
MEASURE 'Sales'Margin = SUMX(Sales, Sales[SalesAmount] - Sales[TotalCost] )
EVALUATE
ADDCOLUMNS (
CALCULATETABLE ( Sales, Sales[StoreKey] = 155 ),
"Margin", [Margin]
)

Filter existing table to another table without adding measures or column on existing table

I want to create a table based on input table.
Input table is:
The new table filters the input table to show the last entry of every day.
I have tried working with measure but sometimes cant tell if it is working right until I graph it in pivot tables which is not so bad but sometimes just doesn't show me what I need to see exactly.
I have tried this measure:
History_Daily Efficiency =
VAR LastDailyEfficiency =
GENERATE(
VALUES ('Table_Full'[Cell]),
CALCULATETABLE (
TOPN (
1,
GROUPBY (
'Table_Full',
'Table_Full'[Date],
'Table_Full'[Time],
'Table_Full'[Efficiency]
),
'Table_Full'[Date], DESC,
'Table_Full'[Time], DESC,
'Table_Full'[Efficiency], ASC
)
)
)
RETURN
CALCULATE (
AVERAGE('Table_Full'[Efficiency]),
TREATAS( LastDailyEfficiency, 'Table_Full'[Cell], 'Table_Full'[Date], 'Table_Full'[Time], 'Table_Full'[Efficiency]),
'Table_Full'[Efficiency] < 80
)
But I got this:
I would like to see this as the output:
You can create a new table:
LastDayCount = GROUPBY(Table_Full;Table_Full[lob/Part Number];Table_Full[Date];"LastDate";MAXX(CURRENTGROUP(); Table_Full[DateTime]))
This will create a table with the last DateTime of the day.
Next we add a column giving us the max of that particular last datetime of the day. I noticed that you have more the same entries, the logic below takes the max part count at the end of the day when more than one entry.
Count =
CALCULATE(MAX(Table_Full[Part Count]);
FILTER(Table_Full;LastDayCount[Table_Full_lob/Part Number] = Table_Full[lob/Part Number]
&& LastDayCount[LastDate] = Table_Full[DateTime]))
End result:

Get first department join date for each client from a different table using DAX

In my scenario, many clients moving between departments and the system is tracking this using a table with columns like: ClientID/ DepartmentID/ Start date.
What if I need to get a column with first department start-date for each client? I am trying to read this to a Client profile table from the above Department association table using DAX:
FIRSTDATE('ClientDepartment'[StartDate]) will give only a single date for all clients. I am looking to get something like:
For Example (see client, department movement and result needed tables:
This is for a tabular model and I am trying to add as a column (not as measure or calculated table).
I tried:
CALCULATE (
FIRSTDATE ( ClientDepartments[StartDate] ),
ClientDepartments[ClientID] = Clients[ClientID]
)
but throwing an error
The expression contains multiple columns, but only a single column can
be used in a True/False expression that is used as a table filter
expression.
If the two tables have an active relationship, such that the Clients table is a dimension table for the ClientDepartments table, then you can simply use the following expression for the calculated column:
CALCULATE ( MIN ( 'ClientDepartments'[StartDate] ) )
If you don't have a relationship in place, use a variable:
VAR currentClient = 'Clients'[ClientID]
RETURN
CALCULATE (
MIN ( 'ClientDepartments'[StartDate] ) ,
'ClientDepartments'[ClientID] = currentClient
)

Including groups with no values in stacked column chart

I'm building a chart that will cumulatively sum Invoice Values for the next month, broken out by category of sale. It looks like this:
My problem is that for particular slicer values, there might not be any invoices for a particular category, and thus the groups just don't show in the graph:
This looks scrappy, so I'm trying to force them to show. Given the rows simply don't exist the way I'm trying to do this is to have a new table which has a row per-date-per-category, and use a measure to cumulatively sum all the data from my source table. So for example given this source table:
I've built the structure of this table, but I need to find a way to add the "Cumulative Value" field that's also shown:
Unfortunately I can't work out how to make that work. The usual cumulative sum syntax would be:
Cumulative Value = (
CALCULATE(
SUM('Table 1'[Value]),
FILTER(ALLSELECTED('Table 1'), ISONORAFTER('Table 1'[Date], MAX('Table 1'[Date]), DESC))
)
)
And I can't seem to add in another filter expression without either
Breaking it such that it returns different values per category but the same value for every date
Breaking it such that it returns different values per date but the same value for each category
So; what Measure can I build to create that "Cumulative Value" field?
Never mind, I got it. Full DAX for the answer was:
CumulativeValue =
VAR CurrActionDate = MAX('Table 2'[Date])
VAR CurrTransType = MAX('Table 2'[Category])
RETURN (
CALCULATE(
SUM('Table 1'[Value],
FILTER(
ALLSELECTED('Table 1'),
'Table 1'[Date] <= CurrActionDate
),
FILTER(
ALLSELECTED('Table 1'),
'Table 1'[Category] = CurrTransType
)
)
)
Ta-da! Cumulative sum across different groups with no blank values.