PowerBI DAX for Finding Last Record - powerbi

Question
What is an efficient way to create a calculated column finding the last value of my DATE column, using the ModifiedOn column, per ID? I don't want the MAX date, just the last record (even if the last record is the minimum). Also, my table is a calculated column.
Example Table
ID
DATE
ModifiedOn
A
2/4/2020
1/16/2019
A
2/5/2020
1/17/2019
B
3/2/2020
2/7/2020
B
3/3/2020
2/8/2020
B
3/1/2020
2/9/2020
Current Formula
LastRecord =
VAR Max_Date =
CALCULATE (
MAX ( 'Table1'[ModifiedOn] ),
ALLEXCEPT ( 'Table1', 'Table1'[ID] )
)
RETURN
IF (
Table1[ModifiedOn] = Max_Date,
Table1[DATE]
)
Current Results
But using the formula I get a calculated column that looks like this:
I keep getting blanks where they should be filled with the LAST recorded date of that ID.

Use the following dax formula to create the expected column:
Column =
VAR __id = 'Table'[ID]
VAR __lastMod =
CALCULATE(
MAX( 'Table'[ModifiedOn] ),
FILTER( 'Table', 'Table'[ID] = __id )
)
VAR __lastDate =
CALCULATE(
MAX( 'Table'[Date] ),
FILTER( 'Table', 'Table'[ID] = __id && 'Table'[ModifiedOn] = __lastMod )
)
Return __lastDate

Related

Is there any DAX Measure that Count rows that have an ID matching another row, but a different value in the column

I have a table with ID and with different statuses but some are not having both. I need create measure that will give the count for all the ID's that are having different statues.
I have tried below Dax functions but not giving the expected results.
Link-EC-Count =
VAR count_Donor =
CALCULATE (
DISTINCTCOUNT ( MagentaBuilt_Linked[Microwave IQ Link ID] ),
FILTER (
ALLEXCEPT ( MagentaBuilt_Linked, MagentaBuilt_Linked[Microwave IQ Link ID] ),
MagentaBuilt_Linked[Site_Nature] = "Donor"
),
FILTER (
MagentaBuilt_Linked,
MagentaBuilt_Linked[Primary AAV Vendor] = "T-Mobile"
)
)
VAR count_Recepient =
CALCULATE (
DISTINCTCOUNT ( MagentaBuilt_Linked[Microwave IQ Link ID] ),
FILTER (
ALLEXCEPT ( MagentaBuilt_Linked, MagentaBuilt_Linked[Microwave IQ Link ID] ),
MagentaBuilt_Linked[Site_Nature] = "Recipient"
),
FILTER (
MagentaBuilt_Linked,
MagentaBuilt_Linked[Primary AAV Vendor] = "T-Mobile"
)
)
RETURN
IF ( count_Donor > 0 && count_Recepient > 0, 1, 0 )
Here is the sample data looks like
Anybody have any ideas?
Here's a calculated column formula for "Eligible Row?" that works:
Eligible Row? =
IF(
CALCULATE(
COUNTROWS('Table'),
FILTER('Table',
'Table'[Affiliate ID]=EARLIER('Table'[Affiliate ID]) &&
'Table'[Achievement Type] <> EARLIER('Table'[Achievement Type])))>0,
"Yes","No")
The idea is to filter the table for rows when the Affiliate ID matches, then filter for rows where the Achievement is different, then count the rows.
Here are formulas for my two intermediate calculated columns:
Count ID =
CALCULATE(
COUNTROWS('Table'),
FILTER('Table',
'Table'[Affiliate ID]=EARLIER('Table'[Affiliate ID])))
Count Other Achievements =
CALCULATE(
COUNTROWS('Table'),
FILTER('Table',
'Table'[Affiliate ID]=EARLIER('Table'[Affiliate ID]) &&
'Table'[Achievement Type] <> EARLIER('Table'[Achievement Type])))
I think This is what you need. Try this code as measure:
Count ID =
VAR TblSummary = ADDCOLUMNS(
SUMMARIZE('Sheet 1','Sheet 1'[Affiliate Id],'Sheet 1'[Achievement Type]),
"UniqueCount",CALCULATE(COUNT('Sheet 1'[Affiliate Id]),ALLEXCEPT('Sheet 1','Sheet 1'[Affiliate Id]))
)
RETURN
SUMX(TblSummary,IF([UniqueCount]>1,[UniqueCount]))
If we test it on a visual:

Show cumulative SalesAmount column chart to max date in slicer

I am looking to build a column chart in Power BI that displays cumulative sales by month up to max date selected in date slicer. I have a supplementary Date2 table that is related to Date table (inactive relation). Tried something like this, but I keep getting all the months irrespective which one is selected in slicer:
Sales to date selected =
VAR ReferenceDate = MAX ( 'Date'[Date] )
Return
CALCULATE ( [SalesAmount],
ALLEXCEPT('Date', 'Date'[Year]),
FILTER( all(Date2[Date]), Date2[Date] <= MAX( Date2[Date] )
&& Date2[Date] <= ReferenceDate),
USERELATIONSHIP ( 'Date'[Date], Date2[Date] )
)
This is what I get as a result (Slicer selects month 7):
It looks like CALCULATE does not honor filter Date2[Date] <= ReferenceDate . What am I doing wrong here?
OK, looks like this scenario solves my issue. I removed inactive relationship between Date and Date2 and introduced active relationship from Sales to Date2.
Sales to date selected =
VAR ReferenceDate = MAX ( 'Date'[Date] )
Return
IF( MAX(Date2[Date]) <= ReferenceDate,
CALCULATE ( [SalesAmount],
ALLEXCEPT('Date', 'Date'[Year]),
Date2[Date] <= MAX( Date2[Date] )
)
)
I made a correction to your code; but It seems that It takes a long time for it to be approved by community members:
So test this:
Sales to date selected =
VAR ReferenceDate =
MAX ( ALLSELECTED ( 'Date2'[Date] ) )
RETURN
CALCULATE (
[SalesAmount],
FILTER ( ALLEXCEPT ( 'Date2', 'Date2'[Year] ), 'Date2'[Date] <= ReferenceDate )
)
Or This:
Sales to date selected =
VAR ReferenceDate =
MAX ( ALLSELECTED ( 'Date2'[Date] ) )
RETURN
CALCULATE (
[SalesAmount],
FILTER ( ALL ( 'Date2'[Date] ), 'Date2'[Date] <= ReferenceDate )
)

Issue with TOPN and SUMMARIZE in Dax

I'm trying to find the top 5 items sales based on the turnover but I keep receiving this error : The expression refers to multiple columns. Multiple columns cannot be converted to a scalar value.
Top_Five_Items_Turnover =
VAR X =
CALCULATE(
TOPN(
5,
SUMMARIZE(
Sales,
Sales[item],
"Top_Five",
Sales[item]
),
[Turnover], DESC
),
Sales[item]
)
RETURN
X
Hi you cannot return a entire table using a measure. instead return values.
Top 5 =
VAR totalSales =
SUM ( Sales[item] )
RETURN
CALCULATE (
totalSales,
FILTER (
VALUES ( Sales[item] ),
IF (
RANKX ( ALL ( Sales[item]), [Turnover], desc) <= 5,
[Total Sales],
BLANK ()
)
)
)

Power BI- Query Edit

I am trying to create new measures that will only show the data value of the Last day every month and another measure will show the data value of every week Saturday in Power BI.
Many thanks in Advance.
The data is continuing and the next series of data will appended data wise
Output:
Need to create a measure which will show only last day of the Week value ( Example- Saturday is my Last of the Week and Count numbers I need to see as output)
Similarly for Month - Last day of the Month I need to see the Numbers of each service.
Do you have Calendar table mark as "Date Table", which is connected by relationship to your Table? If so, then you can use ENDOFMONTH ( 'Calendar'[issue_date] ) to get lastDateOfMonth
then simply:
ShowValueAtLastDayOfMonth =
calculate( sum(Table[Total sale]),
KEEPFILTERS(
filter(ALL('Calendar'[issue_date]),
'Calendar'[issue_date] = ENDOFMONTH ( 'Calendar'[issue_date] )
)
)
)
ShowOnlyOnSaturday =
calculate(sum(Table[Total sale]), KEEPFILTERS( FLITER(ALL('Calendar[issue_date]),
WEEKDAY ( SELECTEDVALUE('Calendar'[issue_date])) = 7 )))
Without a "Date Table" we need to replace 'Calendar'[issue_date] with your Table[Date] and ENDOFMONTH with:
VAR LastDateVisible =
CALCULATE ( MAX ( 'Table'[Date] ) )
VAR LastYearVisible =
YEAR ( LastDateVisible )
VAR LastMonthVisible =
MONTH ( LastDateVisible )
VAR DaysInMonth =
FILTER (
ALL ( 'Table'[Date] ),
YEAR ( 'Table'[Date] ) = LastYearVisible
&& MONTH ( 'Table'[Date] ) = LastMonthVisible
)
VAR LastDayInMonth =
MAXX (
DaysInMonth,
'Table'[Date]
)
VAR Result =
CALCULATETABLE (
VALUES ( 'Table'[Date] ),
'Table'[Date] = LastDayInMonth
)
RETURN
Result

How to calculate rank within Sales ranges

How to calculate rank within Category defined on sales level. Say, that we want to label products with Sales above some threshold with Category "high", and below that threshold with Category "low".
Here is a sample data.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcisqzSwpVtJRSiwoyEkF0oZKsTpIwkmJeUAIZJigipfn56QlpRYVVQLZpqhSyRlQcWOweFhqempJYlJOKlgusagovwS7XEF+SWJJPtwJKHL5eZn5eUDaHNUqHI5GdkEsAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Category = _t, Product = _t, Amount = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Amount", Int64.Type}})
in
#"Changed Type"
My question is a nephew related to its older uncle, who now I want to call in:
Percent Rank within Category =
VAR HasOneValueTrue = HASONEVALUE ( MyTable[Product] )
VAR tbl =
CALCULATETABLE (
VALUES ( MyTable[Product] ),
REMOVEFILTERS ( MyTable[Product] ),
VALUES ( MyTable[Category] )
)
VAR result =
CALCULATE (
DIVIDE (
RANKX (
tbl,
[Sales],
,
ASC
) - 1,
COUNTROWS ( tbl ) - 1
)
)
RETURN
IF (
HasOneValueTrue,
result
)
The difference is that the uncle has Category defined in table column, but now we want to have category calculated on the fly based on sales level. So I tried
replacing the VAR tbl code with the following one with the threshold of 4:
var tbl =
SUMMARIZECOLUMNS (
MyTable[Product],
"CalculatedCategory", IF ( [Sales] > 4, "high", "low" ),
"AggSales", [Sales]
)
Nevertheless, I am not able to refer to such defined variable. I also failed with trial based on creating first a DAX table and then trying to refer to it.
Here are expected results:
References
Here is the family of related questions which members I met on the way while approaching to state this problem.
DAX equivalent of Excel PERCENTRANK.INC per category
DAX RANKX for within Category
DAX REMOVEFILTERS vs ALL
The value parameter in DAX function RANKX
DAX ALLEXCEPT to sum by category of multiple dimension tables
This can be done with a minor modification to my answer here. Copied below:
Percent Rank =
VAR ProductsInCategory =
CALCULATETABLE (
VALUES ( MyTable[Product] ),
ALLSELECTED ( MyTable[Product] )
)
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
IF (
HASONEVALUE ( MyTable[Product] ),
DIVIDE ( RankProduct - 1, COUNTROWS ( ProductsInCategory ) - 1 )
)
First, define the calculated category as you suggested.
CalculatedCategory = IF ( [Sales] > 4, "high", "low" )
Then plug that into a filter in the ProductsInCategory variable.
Exp. Results =
VAR CalculatedCategory = [CalculatedCategory] /*Determine current category*/
VAR ProductsInCategory =
CALCULATETABLE (
VALUES ( MyTable[Product] ),
FILTER (
ALLSELECTED ( MyTable[Product] ),
[CalculatedCategory] = CalculatedCategory /*New Condition*/
)
)
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
IF (
HASONEVALUE ( MyTable[Product] ),
DIVIDE ( RankProduct - 1, COUNTROWS ( ProductsInCategory ) - 1 )
)
Output:
Edit:
To handle the case where there is only 1 product in a category, you can use MAX to disallow a zero value for the denominator.
Exp. Results =
VAR CalculatedCategory = [CalculatedCategory] /*Determine current category*/
VAR ProductsInCategory =
CALCULATETABLE (
VALUES ( MyTable[Product] ),
FILTER (
ALLSELECTED ( MyTable[Product] ),
[CalculatedCategory] = CalculatedCategory /*New Condition*/
)
)
VAR RankProduct = RANKX ( ProductsInCategory, [Sales],, ASC )
RETURN
IF (
HASONEVALUE ( MyTable[Product] ),
DIVIDE (
RankProduct - 1,
MAX ( COUNTROWS( ProductsInCategory ) - 1, 1 )
)
)
Being very grateful to Alexis Olson, I would like to share a different solution I ended up with. The solution proposed by Alexis works well in my simple example, but it did not work in my complex model. In my complex model the RANKX function does not give the expected results. RANKX returns the same rankings for different sales values.
For the time being this is the solution that works without figuring out what causes RANKX to return ties for different sales values.
First of all, defining Category measure:
CalculatedCategory =
SWITCH (
TRUE (),
NOT ( HASONEVALUE ( MyTable[Product] ) ), "total", -- important to handle totals
[Sales] <= 4, "low",
[Sales] > 4, "high",
"other"
)
It is important to exclude totals from Category. I did it by setting up a different category for totals. Otherwise totals will fall into "high" category bucket. It would distort final results.
I have not used RANKX in calculation of Percent Rank within Category. I used MIXTURE OF COUNTROWS and FILTER.
PercentRank within Category =
VAR category = [CalculatedCategory]
VAR ProductSales = [Sales]
VAR ProductsMatching =
COUNTROWS (
FILTER (
ALLSELECTED ( MyTable[Product] ),
[CalculatedCategory] = category
&& [Sales] >= ProductSales
)
)
var ProductsAll =
COUNTROWS (
FILTER (
ALLSELECTED ( MyTable[Product] ),
[CalculatedCategory] = category
)
)
RETURN
DIVIDE (ProductsMatching-1, MAX( ProductsAll-1, 1 ))
I calculated rows of two tables. First table ProductsMatching has all products that have sales in appropriate category and sales that are higher or equal of the product. ProductsAll returns number of products in category.