Power BI DAX Compute Latest Value for filtered rows - powerbi

I have data in a Power BI DirectQuery table that looks line this:
Name Tx TxDate Other Columns
-------------------------------------------------------
A 1 1/1/2017
A 2 1/3/2017
A 3 1/4/2017
B 4 1/5/2017
B 5 1/6/2017
C 6 1/1/2017
C 7 1/2/2017
C 8 1/9/2017
In a table visual, I want to show only the latest rows for each name:
Name Tx TxDate Other Columns
-------------------------------------------------------
A 3 1/4/2017
B 5 1/6/2017
C 8 1/9/2017
However, I am using a slicer to help filter our dates and I want the latest rows that are in the sliced data. For example, if the sliced date range is 1/1/2017 to 1/2/1017, inclusive, I want to show this:
Name Tx TxDate Other Columns
-------------------------------------------------------
A 1 1/1/2017
C 7 1/2/2017
I've been trying to accomplish this by creating a measure with a DAX expression to compute the latest Date for each name, then adding a filter to only show those where LatestTxDate = TxDate, but it is not working:
LastTxDate =
MAXX(
GROUPBY(
Table,
[Name],
"Latest Tx Date",
MAXX(CURRENTGROUP(), Table[TxDate])
),
[Latest Tx Date]
)
The idea being that I calculate a new measure and then only make the row visible if the TxDate = LastTxDate.
Name Tx TxDate LastTxDate Other Columns
-------------------------------------------------------
A 1 1/1/2017 1/1/2017
A 2 1/3/2017 1/1/2017
A 3 1/4/2017 1/1/2017
B 4 1/5/2017
B 5 1/6/2017
C 6 1/1/2017 1/2/2017
C 7 1/2/2017 1/2/2017
C 8 1/9/2017 1/2/2017
This feels embarrassingly simple, but everything that I have tried doesn't work. Any help is appreciated.

I had the same problem as you and spent a whole week trying to solve it, because I couldn't found any guide on the internet. So I thought I could lend you a hand even though this was asked 9 months ago.
First things first: you need to do this with measures, as they're the only thing that is dynamically calculated within a PowerBI report. If you use a calculated column or a M formula inside the Query Editor, it will only be calculated whenever you refresh your data. They won't be affected by slicers and filters inside your report.
After trying a lot of stuff, I came up with the idea of making a measure that checks if each row is the most recent row for each group, then the measure will take a value of '1'. If it's not the last row, it will take a value '0'.
This is how I managed to do that (note: it was NOT that simple):
Build a calendar table that ranges from the minimum to the maximum of your date column. This must be done because if you use the date column itself in the next steps, the data will behave strangely. This new table's column will be used as the date slicer within the report:
Calendar = CALENDAR(MIN('Table'[TxDate]); MAX('Table'[TxDate]))
Now create a new measure in your data table that will filter the dates higher than the selected date in the report slicer and then it will find the latest date for each category or group:
Check =
VAR DateFilter = MAX('Calendar'[Date])
VAR LastDate = CALCULATE(
MAX('Table'[TxDate]);
ALLEXCEPT(
'Table';
'Table'[Name]
);
'Table'[TxDate] <= DateFilter
)
RETURN IF(LASTNONBLANK('Table'[TxDate]; 1) = LastDate; 1; 0)
If you build a table visual with all your 'Table' columns and LastDate as a measure, you will see that each row will have the most recent date of each group as a value for LastDate. Something like this:
Name Tx TxDate LastDate
---------------------------------------
A 1 1/1/2017 1/4/2017
A 2 1/3/2017 1/4/2017
A 3 1/4/2017 1/4/2017
B 4 1/5/2017 1/6/2017
B 5 1/6/2017 1/6/2017
C 6 1/1/2017 1/9/2017
C 7 1/2/2017 1/9/2017
C 8 1/9/2017 1/9/2017
It will be affected by the date slicer if you have one in your report. So the behaviour is right up to this point. Then I use the formula LASTNONBLANK() to give the date column a row context, thus being able now to compare between TxDate and LastDate and if both are the same, Check will take the value '1'.
Name Tx TxDate LastDate Check
---------------------------------------------
A 1 1/1/2017 1/4/2017 0
A 2 1/3/2017 1/4/2017 0
A 3 1/4/2017 1/4/2017 1
B 4 1/5/2017 1/6/2017 0
B 5 1/6/2017 1/6/2017 1
C 6 1/1/2017 1/9/2017 0
C 7 1/2/2017 1/9/2017 0
C 8 1/9/2017 1/9/2017 1
[Check] measure can't be used in a graph visual as of now, so we need to create another measure that will just count all rows in which [Check] takes the vale '1'. This is the simplest step as we just need a SUMX to sum all the rows of a filtered table:
Count of Tx = SUMX(
FILTER('Table'; [Check] = 1);
[Check]
)
Now you have the total count of all of your table rows with the most recent date within the range given by the date slicer. You can use this measure in a graph visual to show how many of those rows correspond to each category. For example, you are able to build a pie chart that shows how many "names" have the value "3" for Tx, how many have the value "5" and so on.
If you want a table visual that shows which is the latest date for each category, you can, instead of [Check], use [LastDate] as a measure like this:
LastDate =
VAR DateFilter = MAX('Calendar'[Date])
RETURN CALCULATE(
MAX('Table'[TxDate]);
ALLEXCEPT(
'Table';
'Table'[Name]
);
'Table'[TxDate] <= DateFilter
)
If you also want a measure that tells you which is the latest Tx for each category, you can change MAX('Table'[TxDate]) for MAX('Table'[Tx]). There are a lot of possibilities. My suggestion is that you study these formulas so you understand what they are doing in every step, so you can modify them for your needs.
You can also combine the two measures and get a table visual like this one:
Name LastTx LastDate
--------------------------
A 3 1/4/2017
B 5 1/6/2017
C 8 1/9/2017
Hope this helps you even 9 months after you asked, or maybe help other people with the same problem as we had.

I don't think you need to get that fancy. The following works for me.
LastTxDate = MAX(Table[TxDate])
Edit:
You'll want to take the max over the Tx values as well instead of listing all of them.
MaxTx = MAX(Table[Tx])
Use both MAX measures in your table instead of treating the Tx as another category.

Related

How do I make my Power BI table dynamic to change with the filters the user selects?

I have a table of calls with a column for phone number and call id. I want to create a visual that shows how many callers called how many times. (e.g. 5 callers called once, 4 called twice etc.) The challenge I am facing is that once I calculate the count of the number of callers that called count times, the table is static and is not affected by the filters on the report (e.g. the date filter).
This is what I have done so far. Is there a better way?
CallerNumber
CallID
DateTime
1
a
2022-01-01
1
b
2022-01-01
2
c
2022-01-02
3
d
2022-01-03
4
e
2022-01-01
4
f
2022-01-05
4
g
2022-01-06
From the above original data, I created a table...
Table1 =
SUMMARIZE(
Query,
Query[CallerNumber],
"Call Count", COUNT(Query[CallId])
)
CallerNumber
Call Count
1
2
2
1
3
1
4
3
and then another table from that table which gave me...
Table2 =
SUMMARIZE (
'Table1',
'Table1'[Call Count],
"Number of Callers", COUNTROWS('Table1')
)
Call Count
Number of Callers
1
2
2
1
3
1
How would I instead show the below if someone were interested in calls on Jan1?
Call Count
Number of Callers
1
1
2
1
Thanks!
CalculatedTable is populated once at powerbi Model refresh, this is why it don't reflect any change in your filters.
A better option is to use a measure:
CountOF = CALCULATE( countrows(VALUES('Table'[CallID])))
Add additional "counter" table with number from 1 to 10 .
how manyCaller = var _virtual = ADDCOLUMNS(VALUES(detail[ids]), "CountOfCalls", [CountOF])
return
CALCULATE( countrows(FILTER(_virtual, [CountOfCalls] = SELECTEDVALUE(counter[CallCount]))))

DAX Summing Values in Another Table

I am new to DAX.
I have 2 tables. Let's call them Table_1 and Table_2.
Let's say they look like this:
Table_1
ID Table_2_ID Person
1 1 Steve
2 1 Steve
3 1 Steve
4 2 John
5 2 John
6 3 Sally
Table_2 Sales
1 100
2 50
3 5
I want to return results that look something like this:
ID Table_2_ID Person Sales
1 1 Steve 100
2 1 Steve 100
3 1 Steve 100
4 2 John 50
5 2 John 50
6 3 Sally 5
How can I return this with a Dax function?
I know I need to use LOOKUPVALUE and/or the RELATED function, in combination with SUM, but I'm not sure how.
I'm not looking to produce a table, but a measure that when I use it in combination with other columns in Power BI, it applies the appropriate amount to each person in Table_1.
This can be done either by a calculated column or by a measure.
CC in Table_1:
Sum_Tab2 =
var t2_ID = [Table_2_ID]
return
CALCULATE(
SUM('Tabel_2'[Sales]),
'Tabel_2'[ID] = t2_ID
)
Measure:
SumTab2_measure =
var currentT2ID = MAX('Tabel_1'[Table_2_ID])
return
CALCULATE(
SUM('Tabel_2'[Sales]),
'Tabel_2'[ID] = currentT2ID
)
No relationships needed. However, for the measure to work in a visual table the [Tabel_2_ID from Tabl_1 needs to be present with this solution.
These may have to be slightly altered depending on your other filter dependencies and such so that they behave as you want them to.

Make first few rows unresponsive to slicer Power BI

I have a data which looks like below:
Brands Sales Category Index
Brand1 588 A 1
Brand2 846 A 2
Brand3 827 A 3
Brand4 951 A 4
Brand5 673 B 5
Brand6 637 B 6
Brand7 575 B 7
Brand8 995 B 8
Btand9 737 C 9
Brand10 661 C 10
Brand11 729 C 11
Brand12 789 C 12
Brand13 836 C 13
Problem statement :
I am trying to put Category as a slicer. However I want the rows for Category A to be present in the table view irrespective of the slicer which is selected.
Example: Lets say if Category B is selected in slicer , in this case the table should return all rows until Rank 8.
Below is an example of the desired output when category C is selected:
As you can see, the visual table has both Category A and Category C.
Similarly when both B and C are selected, I should be able to display all the categories (A,B and C).
What tried:
I was thinking if we can use a conditional DAX which return 1 for selected values in slicers and mark rest as 0, I could use that as a visual filter and filter out 0. I tried various combinations of Filter with in Filters and SELECTCOLUMN but it did not work. Even the below measure returns all the rows instead of Selected values|| category="A"
test1 = CALCULATE(MIN('Table'[Index]),FILTER(ALLEXCEPT('Table','Table'[Brands]),'Table'[Category]=SELECTEDVALUE('Table'[Category]) || 'Table'[Category]="A"))
I also tried something like:
test = var cat = min('Table'[Category]) return IF(cat = SELECTEDVALUE('Table'[Category])||cat="A",1,0)
But this gives all as 1 , doesnot give 0 for rows which does not match the condition (note I have blocked the slicer interaction here)
Any help would be highly appreciated.
First, you need to separate your slicer table as keeping the value in the same table you can not achieve the requirement. You can create custom table with this below code-
considering your base table name sales
Lets create the custom table category list
No relation can be there between table sales and category list
category list =
SELECTCOLUMNS(
sales,
"Category",sales[Category]
)
Now, create the slicer using new custom table category list and create this below Measure-
is filter =
if(
MIN(sales[Category]) = "A",
1,
if (
MIN(sales[Category]) IN VALUES('category list'[Category]),
1,
0
)
)
Here below is a sample output when C selected-

Power BI Measure: Aggregate By, Filter By, Group By, Simple Math

I am attempting to make a measure that calculates:
SUM(Num_Compliant) / SUM(Num_Asked) for a District, filtered to the current Fiscal Year (i.e. Date on or after 07/01/2018, or July 1, 2018).
District Date Section Num_Compliant Num_Asked
A 11/12/2018 I 3 8
A 1/12/2018 I 3 8
A 11/17/2018 II 1 6
A 5/18/2018 II 3 6
B 2/20/2019 I 4 8
B 4/20/2018 I 5 8
B 11/12/2018 II 6 6
B 1/12/2018 II 1 6
C 11/17/2018 I 2 8
C 5/18/2018 I 3 8
C 4/20/2018 II 5 6
With the above sample data, I expect the following results
District Numerator Denominator Value
A 4 14 0.29
B 10 14 0.71
C 2 8 0.25
I intentionally made the denominator different in district C to reflect the fact that sections are sometimes missing.
I have been trying to solve this for about a day, and am brand-new to Power BI, so I apologize if this is a very simple question.
The following measure looks like it solves your needs:
Value =
var __date = DATE(2018,7,1)
var __Numerator = CALCULATE(sum(Compliancy[Num_Compliant]),ALLEXCEPT(Compliancy,Compliancy[Distict]),Compliancy[Date]>__date)
var __Denominator = CALCULATE(sum(Compliancy[Num_asked]),ALLEXCEPT(Compliancy,Compliancy[Distict]),Compliancy[Date]>__date)
return __Numerator/__Denominator
Please note you will have to change "Compliancy" to your table name throughout the DAX formula. Also, the date is currently hard coded into the DAX, it might be best to use a date slicer so you can change the values on the fly. The measure without the date filter hard coded as is as follows:
Value =
var __Numerator = CALCULATE(sum(Compliancy[Num_Compliant]),ALLEXCEPT(Compliancy,Compliancy[Distict]))
var __Denominator = CALCULATE(sum(Compliancy[Num_asked]),ALLEXCEPT(Compliancy,Compliancy[Distict]))
return __Numerator/__Denominator
Table in Power BI:
As a side note of things to watch out for:
The measure "Value" needs to be set to the format "Decimal Place"
with 2 decimals.
The date field must be appropriately set to the
"Date" data type.

Creating a calculated table by passing a measure or parameter

I have a requirement where I have a data like this,
Date Name Age
1-1-2018 A 1
2-2-2018 B 1
3-3-2018 B 1
6-6-2018 C 2
7-7-2018 B 6
I am trying to give a slicer to the user to select the required number of months from the last month.
So to do that, I am using a calculated column like this:
Month Year = DATEDIFF((Table1[Date]), TODAY(), MONTH) + 1
So that changes the data to something like this:
Date Name Age MonthYear
1-1-2018 A 1 7
2-2-2018 B 1 6
3-3-2018 B 1 5
6-6-2018 C 2 2
7-7-2018 B 6 1
The user selects the Month Year from the Slicer.
For example, when he selects 2, I want to display the last 2 months records in the table.
Expected Output:
Date Name Age
6-6-2018 C 2
7-7-2018 B 6
This works for me if I hardcode it like this:
Calculated Table = CALCULATETABLE(Table1,
FILTER(Table1, OR(Table1[MonthYear] > 2, Table1[MonthYear] = 2)))
But it fails when I try to pass the value in the place of 2 dynamically through a measure using SelectedValue function.
Calculated columns and calculated tables cannot reference a slicer value since they are only computed when you load your data.
If you want to apply this filtering to a visual, I'd suggest creating a separate table for your slicer. For example, you could use Months = GENERATESERIES(1,12) and then rename the column Months as well.
Use the Months[Months] column for your slicer and then create a measure which references it to filter your table/matrix visual.
Filter = IF(SELECTEDVALUE(Months[Months]) >= MAX(Table1[Month Year]), 1, 0)
Then use that measure in your Visual level filters box: