Get latest value for each ID in Power BI / DAX measure - powerbi

In Power BI I would like to create a DAX measure that will retrieve the latest string value for specific IDs. Example source table:
Name_ID | Name | DateTime | Value
----------------------------------------------------------
1 | Child_1 | 18.8.2021 12:33:24 | F
32 | Parent_32 | 18.8.2021 11:41:09 | F
13 | Child_1 | 18.8.2021 11:30:58 | E
48 | Parent_48 | 18.8.2021 09:13:11 | F
2 | Child_2 | 17.8.2021 00:09:42 | S
1 | Child_1 | 17.8.2021 23:03:34 | F
48 | Parent_48 | 17.8.2021 21:46:27 | S
6 | Parent_6 | 16.8.2021 17:31:26 | S
.
.
.
specific parents IDs for example here are 6, 32 and 48, so the result should be something like this:
Name_ID | Name | DateTime (of last execution) | Value
------------------------------------------------------------------------------
32 | Parent_32 | 18.8.2021 11:41:09 | F
48 | Parent_48 | 18.8.2021 09:13:11 | F
6 | Parent_6 | 16.8.2021 17:31:26 | S
The result table I'm trying to get is only parents latest appearance and retrieving the whole row or just Value from last column.
This seems so easy in theory and on paper but I just can't seem to get it in DAX I have tried with various calculate formulas but without any result worth mentioning .
I'm beginner in Power Bi and any help would be very appreciated!

You can use a measure like this one, where we check Max Date per Name:
Flag =
var MaxDatePerName = CALCULATE(max(Sheet3[DateTime]), FILTER(ALL(Sheet3), SELECTEDVALUE(Sheet3[Name]) = Sheet3[Name]))
return
if( MaxDatePerName = SELECTEDVALUE(Sheet3[DateTime]) && LEFT(SELECTEDVALUE(Sheet3[Name]),6) = "Parent", 1, BLANK())

With RANKX
Measure2 =
VAR _0 =
MAX ( 'Table 1'[DateTime] )
VAR _00 =
MAX ( 'Table 1'[Name] )
VAR _1 =
CALCULATE (
RANKX (
FILTER ( ALL ( 'Table 1' ), 'Table 1'[Name] = _00 ),
CALCULATE ( MAX ( 'Table 1'[DateTime] ) ),
,
DESC
)
)
VAR _2 =
IF ( _1 = 1 && CONTAINSSTRING ( _00, "Parent" ) = TRUE (), _0, BLANK () )
RETURN
_2

Related

DAX: Calculate differences between 2 years when value is not 0

+---------+-------+---------+
| NAME | YEAR | SCORE |
+---------+-------+---------+
| A | 2019 | 100 |
| B | 2019 | 67 |
| C | 2019 | 38 |
| A | 2020 | 48 |
| B | 2020 | 78 |
| C | 2020 | 0 |
| A | 2021 | 0 |
| B | 2021 | 50 |
| C | 2021 | 100 |
+---------+-------+---------+
I have a data table with structure below and I am trying to create a card which shows the difference between 2 years (current year - previous year) (which will be affected by Name slicer). However I couldnt seem get achieve below requirements. Is there any ways to achieve this?
if the score for previous year is 0, it will find the difference between current year - non 0 year. Example: if 2019 value is 0, it will find the difference between 2021- 2018.
if the current year is 0, it will compare the last 2 non 0 years. Example: 2021 value is 0, it will compare 2020-2019
You can use a measure like this
Measure =
VAR _tbl =
TOPN ( 2, FILTER ( 'Table', 'Table'[SCORE] <> 0 ), 'Table'[YEAR], DESC )
VAR _yr1 =
CALCULATE ( MAX ( 'Table'[YEAR] ), _tbl )
VAR _score1 =
CALCULATE (
MAX ( 'Table'[SCORE] ),
FILTER ( VALUES ( 'Table'[YEAR] ), 'Table'[YEAR] = _yr1 )
)
VAR _yr2 =
CALCULATE ( MIN ( 'Table'[YEAR] ), _tbl )
VAR _score2 =
CALCULATE (
MAX ( 'Table'[SCORE] ),
FILTER ( VALUES ( 'Table'[YEAR] ), 'Table'[YEAR] = _yr2 )
)
RETURN
_score1 - _score2
which will give you this

Select row with MAX value per category Power BI/DAX

How to select the row with a max value per category in DAX/SSAS? Suppose we have table:
+----------+-------+------------+
| Category | Value | Date |
+----------+-------+------------+
| apples | 1 | 2018-07-01 |
| apples | 2 | 2018-07-02 |
| apples | 3 | 2018-07-03 |
| bananas | 7 | 2018-07-04 |
| bananas | 8 | 2018-07-05 |
| bananas | 9 | 2018-07-06 |
+----------+-------+------------+
Desired results are:
+----------+-------+------------+
| Category | Value | Date |
+----------+-------+------------+
| apples | 3 | 2018-07-03 |
| bananas | 9 | 2018-07-06 |
+----------+-------+------------+
From your question it is not clear whether you want to return a table or a measure.
If you need to return a table, then go with this:
calculated_table
:=VAR _categoryfirst=
ADDCOLUMNS (
VALUES ( 'Table'[Category] ),
"MinValue", CALCULATE (MIN ( 'Table'[Value] ),ALL ( 'Table'[Value] ))
)
RETURN
CALCULATETABLE(
SELECTCOLUMNS('Table',
"Category", 'Table'[Category]
"Value", 'Table'[Value]
"Date", 'Table'[Date]
),
KEEPFILTERS (
TREATAS (
_categoryfirst,
'Table'[Category],
'Table'[Value]
)
)
)
Instead, if you want to create a Table visualization with Category, Value, Date showing only the row associated with minimum value I would go with this:
measure:=
VAR _categoryfirst=
CALCULATETABLE(
ADDCOLUMNS (
VALUES ( 'Table'[Category] ),
"MinValue", CALCULATE (MIN ( 'Table'[Value] ),ALL ( 'Table'[Value] ))
),
ALL('Table'[Value]),
ALL('Table'[Date])
)
RETURN
CALCULATE(
MIN('Table'[Value]),
KEEPFILTERS (
TREATAS (
_categoryfirst,
'Table1'[Category],
'Table1'[Value]
)
)
)

DAX conditional sum

How to construct a DAX measure which returns sum of either A or B. The logic is take B if A is empty. So expected results looks like this:
+---+---+----------+
| A | B | Expected |
+---+---+----------+
| 1 | | 1 |
| 1 | | 1 |
| | 2 | 2 |
| 1 | 2 | 1 |
| | 2 | 2 |
+---+---+----------+
| 3 | 6 | 7 |
+---+---+----------+
When I use measure:
Measure = IF(ISBLANK([SUM(tab[A])]), SUM(tab[B]), SUM(tab[A]))
I get 3 for total which is logical but not what I expect.
I'd recommend using a SUMX iterator in this case.
Measure = SUMX ( tab, IF ( ISBLANK ( tab[A] ), tab[B], tab[A] ) )
You might be able to do the following as well:
Measure =
CALCULATE ( SUM ( tab[A] ) ) +
CALCULATE ( SUM ( tab[B] ),
FILTER ( tab, ISBLANK( tab[A] ) )
)

DAX Measure to calculate aggregate data, but group by Case ID

So I have a variable
var varSubItem = CALCULATE (MAX(Outages[SubItem]), Outages[DATE] >= DATE(2019, 07, 14) )
to calculate out items that have had an outage within 1 day. See below.
Then I have another variable
var data =
CALCULATE (
COUNT ( Outages[CASE_ID] ),
ALLSELECTED ( Outages ),
Outages[SubItem] = devices
)
which gives me back the outage count for the devices in the last 2 years. It's only the last two years because my table visual has a filter for that time frame.
I pray that I'm making sense because I have been trying to do this for 2 weeks now.
Devices w Outages 2Yr =
VAR devices =
CALCULATE ( MAX ( Outages[DEVICE_ID] ), Outages[DATE] >= DATE ( 2019, 07, 14 ) )
VAR data =
CALCULATE (
COUNT ( Outages[CASE_ID] ),
ALLSELECTED ( Outages ),
Outages[DEVICE_ID] = devices
)
RETURN data
I'm getting this,
| Area | Item | SubItem | Case | Date | Outage Count |
|--------|------|---------|-----------|-----------------|--------------|
| XXXXX' | ABC1 | 123A | 123456789 | 7/14/19 1:15 AM | 1 |
| | ABC2 | 123B | 132456798 | 7/14/19 3:20 AM | 1 |
| | ABC3 | 123C | 984561325 | 7/14/19 6:09 PM | 1 |
| | ABC4 | 123D | 789613453 | 7/14/19 3:54 PM | 3 |
| | ABC5 | 123E | 335978456 | 7/14/19 2:10 PM | 2 |
| Total | | | | | 8 |
When I should be getting this,
| Area | Item | SubItem | Case | Date | Outage Count |
|--------|------|---------|-----------|-----------------|--------------|
| XXXXX' | ABC1 | 123A | 123456789 | 7/14/19 1:15 AM | 1 |
| | ABC2 | 123B | 132456798 | 7/14/19 3:20 AM | 1 |
| | ABC3 | 123C | 984561325 | 7/14/19 6:09 PM | 1 |
| | ABC4 | 123D | 789613453 | 7/14/19 3:54 PM | 1 |
| | ABC4 | 123D | 789613211 | 4/19/18 4:20 AM | 1 |
| | ABC4 | 123D | 789611121 | 9/24/17 5:51 AM | 1 |
| | ABC5 | 123E | 335978456 | 7/14/19 2:10 PM | 1 |
| | ABC5 | 123E | 335978111 | 2/21/19 7:19 AM | 1 |
| Total | | | | | 8 |
I think what you want is closer to this:
Devices w Outages 2Yr =
VAR devices =
CALCULATETABLE (
VALUES ( Outages[SubItem] ),
ALLSELECTED ( Outages ),
Outages[DATE] >= TODAY() - 1
)
RETURN
CALCULATE (
COUNT ( Outages[Case] ),
FILTER ( Outages, Outages[SubItem] IN devices )
)
This creates a list of SubItem values rather than the single one you get with MAX and that's where your ALLSELECTED function needs to go.
Edit: To total at the SubItem level try this tweak:
Devices w Outages 2Yr =
VAR devices =
CALCULATETABLE (
VALUES ( Outages[SubItem] ),
ALLSELECTED ( Outages ),
Outages[DATE] >= TODAY() - 1,
VALUES ( Outages[SubItem] )
)
RETURN
CALCULATE (
COUNT ( Outages[Case] ),
ALLSELECTED ( Outages ),
Outages[SubItem] IN devices
)
The exact logic here is a bit complex for a beginner DAX user, but just keep in mind that DAX is all about filters.
For the variable devices, we want a list of all SubItem values in the current context subject to a date constraint. The CALCULATETABLE function allows us to modify our filter context. The ALLSELECTED function is a table filter removes any filter context from the visual so that all Date and Case values that aren't filtered out by slicers or page/report level filters are included. Otherwise, you'd get blanks for rows that have dates before TODAY()-1. The date value boolean filtering is self-explanatory, but then I add another table filter at the end, VALUES(Outages[SubItem]), to add back the SubItem context from the visual.
The CALCULATE piece functions similarly. We count all the Case values after altering the filter context to remove filter context on Case and Date and only taking SubItem values from the list generated in the variable.

Daily Rank Power BI

I have a table with the following headers:
Dates | Category | Value
1/1/00 | A | 100
1/1/00 | B | 200
1/2/00 | A | 300
1/2/00 | B | 100
What I would like to do is to be able to add a custom column with the daily rank as such:
Dates | Category | Value | Rank
1/1/00 | A | 100 | 1
1/1/00 | B | 200 | 2
1/2/00 | A | 300 | 2
1/2/00 | B | 100 | 1
My goal is to run calcs over the top for average rank, etc. How would I write the DAX code for this column?
Cheers
Try this as a calculated column:
Column =
VAR rankValue = 'table'[Value]
RETURN
CALCULATE (
RANK.EQ ( rankValue, 'table'[Value], ASC ),
ALLEXCEPT ( 'table', 'table'[Dates] )
)