I have a table with data. I want to find the average by Criteria 1 for each Department ID (Department IDs are repeated) and output the value of the Department ID that has the maximum average. How can I do this? [I attach a table with data.]
Department ID
Criteria 1
DEP 001
4
DEP 002
2
DEP 003
1
DEP 004
5
DEP 001
3
DEP 003
2
DEP 002
4
DEP 001
3
DEP 004
2
DEP 001
1
DEP 002
3
DEP 003
4
Average(DEP 001) = (4+3+3+1)/4 = 11/4 = 2.75
Average(DEP 002) = (2+4+3)/3 = 9/3 = 3
Average(DEP 003) = (1+2+4)/3 = 7/3 = 2.3
Average(DEP 004) = (5+2)/2 = 7/2 = 3.5
MAX(Average(DEP 001), Average(DEP 002), Average(DEP 003), Average(DEP 004)) = 3.5
Result = DEP 004
first let's create the average table
Modelling --> New Table
average table =
ADDCOLUMNS (
SUMMARIZE ( YourTableName, YourTableName[Department ID ] ),
"avg",
CALCULATE (
AVERAGE ( YourTableName[Criteria 1] ),
ALLEXCEPT ( YourTableName, YourTableName[Department ID ] )
)
)
then let's create the card which shows the max
Maximum Average =
VAR _max =
MAX ( 'average table'[avg] )
RETURN
LOOKUPVALUE ( 'average table'[Department ID ], 'average table'[avg], _max )
but, like your first post, if you have more than 1 criteria, you should unpivot and find a solution after the unpivoting ;)
Here is a measure that does this directly without adding bloat in your model:
ID of Max Avg =
VAR _tbl =
SUMMARIZE (
'Table' ,
'Table'[Department ID] ,
"Avg" , AVERAGE ( 'Table'[Criteria 1] )
)
VAR _top =
TOPN (
1 ,
_tbl ,
[Avg] ,
DESC
)
RETURN
CALCULATE (
SELECTEDVALUE ( 'Table'[Department ID] ) ,
_top
)
Here the measure is used in a Card visual using your sample data:
CALCULATE(
SELECTEDVALUE(tbl[Department ID])
,FILTER(
VALUES(tbl[Department ID])
,CALCULATE(AVERAGE(tbl[Criteria 1]))=MAXX(
VALUES(tbl[Department ID])
,CALCULATE(Average(tbl[Criteria 1]))
)
)
)
Related
I have the following data:
Country Sales
1 20
1 30
1 10
2 25
2 80
3 200
3 4
4 20
5 30
I want to have top 2 country sales summed up and the rest
Country Sales
2 105
3 204
Others 110
I want to display the summed up data in a pie chart.
Rank Sales =
RANKX(ALL(Table[Country]),CALCULATE(sum(Table[Sales])))
What should I do ahead? The if condition is giving an error:
Rank Display =
IF('DAX Measures'[Rank Sales]>2,"Other",'Table'[country])
Please create a new table, and paste this code:
CategorizationByRank =
VAR Summary_01 =
ADDCOLUMNS (
VALUES ( 'Table'[Country] ),
"Total", CALCULATE ( SUM ( 'Table'[Sales] ) )
)
VAR Summary_02 =
ADDCOLUMNS ( Summary_01, "Ranking", RANKX ( Summary_01, [Total] ) )
VAR TablesRankLess_And_Equal_To_2 =
FILTER ( Summary_02, [Ranking] <= 2 )
VAR TablesRankGreater_Than_2 =
ROW (
"Country", "Others",
"Total", SUMX ( FILTER ( Summary_02, [Ranking] > 2 ), [Total] ),
"Ranking", 3
)
VAR UnionAllRecords =
UNION ( TablesRankGreater_Than_2, TablesRankLess_And_Equal_To_2 )
RETURN
UnionAllRecords
And It produces this result:
Then you can put the fields directly into a pie chart, see the picture:
I have two tables - Customer and Transaction. The transaction holds invoices and payments. I need to get the date when the transaction sum is 0 or grater.
So the expected result should be John 02-20-2021. How can I achieve this?
customerID
Name
1
John
2
Ben
customerID
value
date
1
-150
02-13-2021
1
100
02-14-2021
1
200
02-20-2021
1
10
02-23-2021
You can try this out, by adding some new measures.
First measure to calculate the account balance over dates, returning a value only for positive balance:
Account Balance :=
VAR _date = MAX ( Transaction[date] )
VAR _balance =
CALCULATE (
SUM ( Transaction[value] ) ,
Transaction[date] <= _date
)
RETURN
IF ( _balance >= 0 , _balance )
The second filters the original table based on this measure and returns the earliest date:
Break Even Date :=
MINX (
FILTER (
VALUES ( Transaction[date] ),
[Account Balance]
),
[date]
)
Result:
Do note that I have not tested this beyond your (simple) example.
I have data like this,
App_Num Days Price
A1 10 100
A1 11 150
A2 11 200
A3 12 250
A3 12 300
A4 20 350
A4 21 400
The average of the days is displayed on a card visual as 13.857.
Now, there are two parameters that are set for user to adjust the values and see.
Total Value (Min and Max Range)
Days
For example, if the user selects 0-280- it is expected to list A1 (100 + 150 = 250 less than 280) and A2 (200 being less than 280).
I used a DAX like this and built a table like this,
Apps_in_scope =
Var min_amount = Min('Total Value'[Total Value])
Var max_amount = Max('Total Value'[Total Value])
var required_app_num = SELECTEDVALUE(Table1[App_Num])
Var required_amount = CALCULATE(sum(Table1[Price]),FILTER(Table1,Table1[App_Num] = required_app_num))
var in_scope = if(And(required_amount <= max_amount, required_amount >= min_amount),1,0)
return in_scope
And I was able to produce a Visual like this,
App_Num Apps_in_scope
A1 1
A2 1
A3 0
A4 0
Now after selecting the total price range, if the user selects the days parameter manually to be 15 then my average will shift as per this logic.
A1 has 2 transactions and with in the selected price range of 280 will become (15*2)
A2 has 1 transaction and with in the selected price range of 280 become (15*1)
A3 has 2 transaction and will remain unchanged (12+12)
A4 has 2 transactions and will remain unchanged (20+21)
So my new measure which I want to place on the card is expected to show now (15+15+15+12+12+20+21)/7 = 15.714
How can I write this measure. Kindly help me with this
I'd tweak your measure slightly so that it works better for taking the average:
Apps_in_scope_2 =
VAR min_amount = MIN ( 'Total Value'[Total Value] )
VAR max_amount = MAX ( 'Total Value'[Total Value] )
VAR required_amount =
CALCULATE ( SUM ( Table1[Price] ), ALLEXCEPT ( Table1, Table1[App_Num] ) )
VAR in_scope =
IF ( AND ( required_amount <= max_amount, required_amount >= min_amount ), 1, 0 )
RETURN
in_scope
With this tweak the average is fairly simple:
AvgMeasure =
VAR DaysParam = SELECTEDVALUE ( DaysSlicer[Days] )
RETURN
AVERAGEX( Table1, IF( [Apps_in_scope_2] = 1, DaysParam, Table1[Days] ) )
Edit:
Here's an alternative version that doesn't use the first measure but should scale better to large data tables.
AvgAlternate =
VAR min_amount = MIN ( 'Total Value'[Total Value] )
VAR max_amount = MAX ( 'Total Value'[Total Value] )
VAR DaysParam = SELECTEDVALUE ( DaysSlicer[Days] )
VAR apps =
ADDCOLUMNS (
SUMMARIZE (
Table1,
Table1[App_Num],
"#Price", SUM ( Table1[Price] ),
"#Rows", COUNT ( Table1[Price] )
),
"#Days",
IF (
AND ( [#Price] <= max_amount, [#Price] >= min_amount ),
DaysParam * [#Rows],
CALCULATE ( SUM ( Table1[Days] ) )
)
)
RETURN
DIVIDE ( SUMX ( apps, [#Days] ), SUMX ( apps, [#Rows] ) )
This is assuming that you have separate tables for your Price range and Days selection (as in what-if parameter tables).
My measure =
VAR apps =
SELECTCOLUMNS (
FILTER (
SUMMARIZE ( Table1, Table1[App_Num], "Total Price", SUM ( Table1[Price] ) ),
[Total Price] >= MIN ( 'Total Value'[Total Value] )
&& [Total Price] <= MAX ( 'Total Value'[Total Value] )
),
"App_Num", [App_Num]
)
RETURN
AVERAGEX (
Table1,
IF ( Table1[App_Num] IN apps, SELECTEDVALUE ( Days[Days] ), Table1[Days] )
)
I have 2 tables, the first is a sanitised version of the data, the second is what I need to calculate.
AnimalCount
Animal DATE Count
Lion 2019-01-01 2
Cat 2019-01-01 45
Cat 2019-01-02 40
Fish 2019-01-02 900
Cat 2019-01-03 50
Fish 2019-01-05 800
Fish 2019-01-06 1200
Cat 2019-01-07 45
Lion 2019-01-07 1
Lion 2019-01-08 0
Calculated
DATE (unique) Sum of latest Count by Animal
2019-01-01 47 = 45 Cats + 2 Lions
2019-01-02 942 = 900 Fish + 40 Cats + 2 Lions
2019-01-03 952 = 50 Cats + 900 Fish + 2 Lions
2019-01-05 852 = 800 Fish + 50 Cats + 2 Lions
2019-01-06 1252 = 1200 Fish + 50 Cats + 2 Lions
2019-01-07 1246 = 1 Lion + 45 Cats + 1200 Fish
2019-01-08 1245 = 45 Cats + 1200 Fish
Here are the queries I've tried so far, both of them give slightly different results to what I'm looking for.
I'd be super grateful for any suggestions?
Query 1.
LatestTotal = SUMX(
GROUPBY(
FILTER(
AnimalCount,
[DATE] <= EARLIER([DATE])
),
[Animal],
"LatestGroupTotal",
SUMX(CURRENTGROUP(), [Count])
),
[LatestGroupTotal]
)
Query 2.
LatestTotal = SUMX(
ADDCOLUMNS(
ADDCOLUMNS(
VALUES(AnimalCount[Animal]),
"AnimalName",
[Animal],
"LastDate",
CALCULATE(
MAX(AnimalCount[DATE]),
NOT(ISBLANK(AnimalCount[Count]))
)
),
"LastValue",
SUMX(
FILTER(
AnimalCount,
[AnimalName] = [Animal]
&& [DATE] = [LastDate]
),
[Count]
)
),
[LastValue]
)
First, create a measure for total animal count (for further convenience):
Total Animal Count = SUM(AnimalCount[Count])
Then, add this measure:
Latest Total =
VAR
Current_Date = MAX ( AnimalCount[DATE] )
VAR
All_Latest_Dates =
ADDCOLUMNS (
ALL ( AnimalCount[Animal] ),
"Last Date", CALCULATE (
MAX ( AnimalCount[DATE] ),
AnimalCount[DATE] <= Current_Date )
)
VAR Animal_Latest_Dates =
TREATAS ( All_Latest_Dates, AnimalCount[Animal], AnimalCount[DATE] )
RETURN
CALCULATE ( [Total Animal Count], Animal_Latest_Dates )
Result:
Explanation:
This formula requires an understanding of "data lineage" concept in DAX:
Understanding Data Lineage in DAX
In short:
store date visible in a current context in a variable;
then, generate a virtual table ("All_Latest_Dates"), that consists of all animals, and their last known date for each "current" date;
next, apply this virtual table to the AnimalCount table using TREATAS (please read the article to understand how it works);
finally, calculate animal count using the virtual table as a new filter context.
This approach results in an optimal query execution plan, and the formula should give you good performance even if your data is large.
How about this?
LatestTotal =
VAR CurrDate =
MAX ( AnimalCount[DATE] )
VAR Summary =
SUMMARIZE (
FILTER ( ALLSELECTED ( AnimalCount ), AnimalCount[DATE] <= CurrDate ),
AnimalCount[Animal],
"LastDate", MAX ( AnimalCount[DATE] )
)
VAR CountAtDate =
ADDCOLUMNS (
Summary,
"Count", LOOKUPVALUE (
AnimalCount[Count],
AnimalCount[Animal], [Animal],
AnimalCount[DATE], [LastDate]
)
)
RETURN
SUMX ( CountAtDate, [Count] )
First, we summarize the table by Animal looking for the last date associated with each one that is less than or equal to the date of the row we're in (CurrDate).
Then we look up the count for that animal on that date and add all those counts together.
I have a table like this :
Id numbers_old numbers_new date
1 5 0 2019-02-13
1 8 3 2019-02-14
2 2 0 2019-02-13
2 12 10 2019-02-14
2 15 5 2019-02-15
I want a measure which will calculate volume_total = (number_old where date=min(date)) + (numbers_new where date != min(date))
How can I achieve it with a Power BI measure?
You can write the measure:
volume_total =
VAR DateMin =
MIN ( Table1[date] )
VAR SumOld =
CALCULATE (
SUM ( Table1[numbers_old] ),
Table1[date] = DateMin
)
VAR SumNew =
CALCULATE (
SUM ( Table1[numbers_new] ),
Table1[date] <> DateMin
)
RETURN
SumOld + SumNew
Worked example PBIX file: https://pwrbi.com/so_54707672/