I want to list only the max and the min of the sums grouped by date where count of the Name is above 2. Below formula works fine to find the max
Maks =
maxx(
SUMMARIZE('Table',
'Table'[DateStamp],
"Total",
CALCULATE(sum('Table'[Value]),
filter('Table', count('Table'[Name])>2))
),[Total]
)
sample data
DateStamp Name Value
7.7.2022 A 55
7.7.2022 B 88
7.7.2022 C 77
8.7.2022 A 125
8.7.2022 B 25
8.7.2022 C 54
9.7.2022 A 61
9.7.2022 C 88
10.7.2022 A 92
10.7.2022 B 113
10.7.2022 C 145
11.7.2022 A 155
11.7.2022 C 255
12.7.2022 A 107
12.7.2022 B 121
12.7.2022 C 167
Desired Output is
12.07.2022 395
8.07.2022 204
tablo =
VAR tbl =
FILTER(
SUMMARIZE(ALL('Table'),'Table'[DateStamp])
,CALCULATE(
DISTINCTCOUNT('Table'[Name])
,ALLEXCEPT('Table','Table'[DateStamp])
)>2
)
VAR tblFiltered =
FILTER(
ADDCOLUMNS(
tbl
,"SUM",CALCULATE(SUM('Table'[Value]))
)
,OR(
[SUM]=MAXX(tbl,CALCULATE(SUM('Table'[Value])))
,[SUM]=MINX(tbl,CALCULATE(SUM('Table'[Value])))
)
)
RETURN
SUMX(FILTER(tblFiltered,[DateStamp]=SELECTEDVALUE('Table'[DateStamp])),[SUM])
This is another solution. I am using DAX.do software to write my dax codes which I think is more efficient. so If you decide to copy and use codes, please do not forget to remove evaluate and give a name to your table, column or whatever....
let's go step by step:
1st Step - Create our table
DEFINE
TABLE Records =
SELECTCOLUMNS (
{
( dt"2022-07-07", "A", 55 ),
( dt"2022-07-07", "A", 55 ),
( dt"2022-07-07", "B", 88 ),
( dt"2022-07-07", "C", 77 ),
( dt"2022-07-08", "A", 125 ),
( dt"2022-07-08", "B", 25 ),
( dt"2022-07-08", "C", 54 ),
( dt"2022-07-09", "A", 61 ),
( dt"2022-07-09", "C", 88 ),
( dt"2022-07-10", "A", 92 ),
( dt"2022-07-10", "B", 113 ),
( dt"2022-07-10", "C", 145 ),
( dt"2022-07-11", "A", 155 ),
( dt"2022-07-11", "C", 255 ),
( dt"2022-07-12", "A", 107 ),
( dt"2022-07-12", "B", 121 ),
( dt"2022-07-12", "C", 167 )
},
"DateStamp", [Value1],
"Name", [Value2],
"Value", [Value3]
)
EVALUATE
Records
DEFINE
MEASURE Records[TotalCount] = COUNT ( Records[Name] )
EVALUATE
ROW("TotalCount",[TotalCount])
EVALUATE
VAR Maks = MAXX(ADDCOLUMNS (
SUMMARIZE ( Records, Records[DateStamp]),
"Total", CALCULATE ( SUM ( Records[Value] ) )
),IF([TotalCount]>2,[Total]))
VAR MinK = MINX (ADDCOLUMNS (
SUMMARIZE ( Records, Records[DateStamp]),
"Total", CALCULATE ( SUM ( Records[Value] ) )
),IF([TotalCount]>2,[Total]))
VAR Maks_Date = MAXX(FILTER (ADDCOLUMNS (
SUMMARIZE ( Records, Records[DateStamp]),
"Total", CALCULATE ( SUM ( Records[Value] ) )
),[Total] = Maks),[DateStamp])
VAR Min_Date = MINX(FILTER (ADDCOLUMNS (
SUMMARIZE ( Records, Records[DateStamp]),
"Total", CALCULATE ( SUM ( Records[Value] ) )
),[Total] = MinK),[DateStamp])
RETURN
SELECTCOLUMNS (
{(Maks_Date,Maks),
(Min_Date,MinK)},
"MaxDate-MinDate",[Value1],
"MaxValue-MinValue",[Value2]
)
Related
I'm trying to find out how to choose first and last date and quantity for each category, here ORDER_LINE_RELEASE_NO.
ORDER_LINE_RELEASE_NO
WANTED_DATE_OLD
WANTED_DATE_NEW
BUY_QTY_DUE_OLD
BUY_QTY_DUE_NEW
49562_1_9
27.01.2022
1
49562_1_9
27.01.2022
27.01.2022
1
2660
50081_1_1
31.01.2022
6
50081_1_1
31.01.2022
31.03.2022
6
6
50081_1_1
31.03.2022
31.03.2022
6
1210
50084_1_1
10.02.2022
1
50084_1_1
10.02.2022
10.03.2022
1
1
50084_1_1
10.03.2022
10.06.2022
1
1
50084_2_1
10.02.2022
60
50084_2_1
10.02.2022
08.04.2022
60
60
52370_1_1
13.05.2022
3000
52370_1_1
13.05.2022
13.05.2022
3000
2000
In this original table I have the same ORDER_LINE_RELEASE_NO in more rows and I would like to "summarize" it like in the second table here:
ORDER_LINE_RELEASE_NO
FIRST_DATE
LAST_DATE
ORIGINAL_QTY
LAST_WANTED_QTY
49562_1_9
27.01.2022
27.01.2022
1
2660
50081_1_1
31.01.2022
31.03.2022
6
1210
50084_1_1
10.02.2022
10.06.2022
1
1
50084_2_1
10.02.2022
08.04.2022
60
60
52370_1_1
13.05.2022
13.05.2022
3000
2000
So basically in the column FIRST_DATE we have the first value from column WANTED_DATE_NEW (for each category), in LAST_DATE the last value from WANTED_DATE_NEW, in ORIGINAL_QTY is the first value from BUY_QTY_DUE_NEW and in LAST_WANTED_QTY we have the last value from BUY_QTY_DUE_NEW.
I tried to use FIRSTNONBLANK and LASTNONBLANK functions, but they only work fot dates, not for all quantity - for example for 52370_1_1 quantity.
My code in creating new table from another in powerBI was:
PURCH_ORD_LINE_UNIQUE =
ADDCOLUMNS (
DISTINCT ( PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] ),
"FIRST_DATE",
CALCULATE (
FIRSTNONBLANK (
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW],
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW]
),
ALLEXCEPT ( PURCH_ORD_LINE_ARCH, PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] )
),
"LAST_DATE",
CALCULATE (
LASTNONBLANK (
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW],
PURCH_ORD_LINE_ARCH[WANTED_DATE_NEW]
),
ALLEXCEPT ( PURCH_ORD_LINE_ARCH, PURCH_ORD_LINE_ARCH[ORDER_LINE_RELEASE_NO] )
),
"ORIGINAL_QTY",
CALCULATE (
FIRSTNONBLANK (
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW],
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW]
)
),
"LAST_WANTED_QTY",
CALCULATE (
LASTNONBLANK (
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW],
PURCH_ORD_LINE_ARCH[BUY_QTY_DUE_NEW]
)
)
)
Sorry if my question is too stupid, I'm quite new to DAX and PowerBI.
Thanks for any answer.
Tomas
here is my solution : (i will share the sample file at the end, so you can easily understand my approach)
First we will add an index column to the table :
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type)
then, we will add grouped index number column :
Group Ranking =
RANKX (
FILTER (
'Table',
EARLIER ( 'Table'[ORDER_LINE_RELEASE_NO ] ) = 'Table'[ORDER_LINE_RELEASE_NO ]
),
'Table'[Index],
,
ASC,
DENSE
)
finally, we create our table :
Modelling --> New Table
Result Table =
ADDCOLUMNS (
SUMMARIZE ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
"FIRST_DATE", CALCULATE ( MIN ( 'Table'[WANTED_DATE_OLD ] ) ),
"LAST_DATE", CALCULATE ( MAX ( 'Table'[WANTED_DATE_new ] ) ),
"ORIGINAL_QTY",
VAR _max =
CALCULATE (
MIN ( 'Table'[Group Ranking] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
NOT ( ISBLANK ( 'Table'[BUY_QTY_DUE_OLD ] ) )
)
RETURN
CALCULATE (
FIRSTNONBLANK ( 'Table'[BUY_QTY_DUE_OLD ], 1 ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
'Table'[Group Ranking] = _max
),
"LAST_WANTED_QTY",
VAR _max =
CALCULATE (
MAX ( 'Table'[Group Ranking] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] )
)
RETURN
CALCULATE (
SUM ( 'Table'[BUY_QTY_DUE_NEW] ),
ALLEXCEPT ( 'Table', 'Table'[ORDER_LINE_RELEASE_NO ] ),
'Table'[Group Ranking] = _max
)
)
Here is the sample PBix File for you...
How can I write a measure to count the number of userID for which sum(x1) is equal to count(order_id), in Power BI?
For example, my data table is:
userID
x1
order_id
141
1
719
172
0
616
172
0
189
172
0
2211
172
0
317
1103
1
98
1103
1
213
1103
1
15
2524
0
4902
2524
1
3620
and I use table visual of power bi for this, to explain my mean:
userID
sum(x1)
count(order_id)
141
1
1
172
0
4
1103
3
3
2524
1
2
Note that the userID column is one of the columns in my data table, and calculating sum(x1) and count(order_id) in this sample is by Power BI default features.
The result for this sample should be 2. I need a measure that returns 2.
Measure1 =
VAR _base1 =
SUMMARIZE ( 'Table 1', 'Table 1'[userID] )
VAR _base2 =
ALLEXCEPT ( 'Table 1', 'Table 1'[userID] )
VAR _ct =
ADDCOLUMNS ( _base1, "X", CALCULATE ( COUNT ( 'Table 1'[order_id] ), _base2 ) )
VAR _sum =
ADDCOLUMNS ( _base1, "X", CALCULATE ( SUM ( 'Table 1'[x1] ), _base2 ) )
VAR _nt =
NATURALINNERJOIN ( _sum, _ct )
RETURN
COUNTROWS ( _nt )
or
Measure4 =
VAR _1 =
COUNTX (
VALUES ( 'Table 1'[userID] ),
VAR _base =
ALLEXCEPT ( 'Table 1', 'Table 1'[userID] )
VAR _1 =
CALCULATE ( SUM ( 'Table 1'[x1] ), _base )
VAR _2 =
CALCULATE ( COUNTROWS ( 'Table 1' ), _base )
VAR _3 =
IF ( _1 = _2, 1 )
RETURN
_3
)
RETURN
_1
This should work
count_valid_rows =
VAR sum_x1_table =
SUMMARIZECOLUMNS ( 'table'[userID], 'table', "sumx1", SUM ( 'table'[x1] ) )
VAR count_orderId_table =
SUMMARIZECOLUMNS (
'table'[userID],
'table',
"countOfOrders", COUNT ( 'table'[x1] )
)
RETURN
COUNTROWS (
FILTER (
NATURALINNERJOIN ( sum_x1_table, count_orderId_table ),
[sumx1] = [countOfOrders]
)
)
Docs of the functions used.
NATURALINNERJOIN
SUMMARIZECOLUMNS
Another suggestion:
Count :=
SUMX (
SUMMARIZECOLUMNS (
'Table'[userID] ,
"Sum" , SUM ( 'Table'[x1] ),
"Count" , COUNT ( 'Table'[order_id] )
),
IF ( [Sum] = [Count] , 1 )
)
As you see from the other answers there are heaps of ways to calculate this. I suggest you look over all the suggestions to understand what is going on in each, and then write out your preferred way of dealing with this type of issue after.
Your new measure may looks like this one:
calculate( countrows('YourTabel'), FILTER(ALL('YourTabel'), somestatementIfneeded && var __x1 = [x1] var __x2 = [x2] return __x1 = __x2))
The main part is to use variable PLACEHOLDER;
My data:
week
sale
20
50
20
20
21
10
21
10
22
5
22
5
Desired result:
week
sale
change
20
50
any
20
20
any
21
10
-50
21
10
-50
22
5
-10
22
5
-10
Where:
Week 20 total = 70,
Week 21 total = 20,
Week 22 total = 10
Diff for week 21 = 20-70 = -50
Diff for week 22 = 10-20 = -10
Note: "any" = can be anything (i.e. 0 or null)
Calculated column
Column 2 =
VAR _1 =
CALCULATE ( MAX ( 'Table'[week] ) ) - 1
VAR _2 =
SUMX ( FILTER ( ALL ( 'Table' ), 'Table'[week] = _1 ), 'Table'[sale] )
VAR _3 =
CALCULATE ( SUM ( 'Table'[sale] ), ALLEXCEPT ( 'Table', 'Table'[week] ) )
VAR _4 =
IF ( ISBLANK ( _2 ) = TRUE (), BLANK (), _3 )
RETURN
_4
Measure
currentWeekTotal:= SUM('Table'[sale])
prevWeekTotal:=
VAR _1 = MAX('Table'[week])-1
VAR _2 = SUMX(FILTER(ALL('Table'),'Table'[week]=_1),'Table'[sale])
RETURN _2
change:= IF([prevWeekTotal]=BLANK(),BLANK(),[currentWeekTotal]-[prevWeekTotal])
Here is a simple code for a calculated column :
change =
VAR _firstweek = MIN ( 'Table'[week] )
VAR _thisweek = 'Table'[week]
VAR _thisweeksales = CALCULATE ( SUM ( 'Table'[sale] ) , ALLEXCEPT ( 'Table' , 'Table'[week] ) )
VAR _lastweeksales = CALCULATE ( SUM ( 'Table'[sale] ) , ALL ( 'Table' ) , 'Table'[week] = _thisweek - 1 )
VAR _diff = IF ( _thisweek <> _firstweek , _thisweeksales - _lastweeksales )
RETURN _diff
This also handles skipped weeks that are not the first week.
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] )
)
This is something I have never attempted before
I want to calculate the weighted standard deviation and the weighted average for the dataset containing records for actual values measured against set values
The calculation is to be done using a DAX query in PowerBI
Set Value 1
Actual Value 1
Set Value 2
Actual Value 2
10
8
101
102
10
11
101
104
10
12
101
97
10
7
101
99
10
13
101
97
10
13
101
100
10
9
101
98
10
10
101
100
10
8
101
102
10
14
101
98
10
8
101
98
10
13
101
96
10
13
101
103
10
14
101
102
10
7
202
205
20
18
202
198
20
18
202
197
20
19
202
203
20
19
202
202
20
19
202
201
20
22
202
202
20
18
202
200
20
17
202
195
20
23
202
198
Edit 1:
Please use the data above.
Also, please note that although, set points are what we intend to use as weights but its the count of a particular set point. for eg: if the setpoint1 10 is repeating 15 times and set point1 20 is repeating 9 times then wieght to be used as 15 & 9 respectively
Weighted Average and Standard deviation can be implemented in DAX according to their mathematical definition.
Assuming we have a table with the columns Weight and Value the formula for the Weighted Average is
WAvg =
VAR Num = SUMX( Samples, Samples[Weight] * Samples[Value] )
VAR Den = SUM( Samples[Weight] )
RETURN DIVIDE( Num, Den )
and the formula for the Weighted Standard Deviation is
WStdDev =
VAR WAvg = [WAvg]
VAR Num = SUMX( Samples, Samples[Weight] * (Samples[Value] - Wavg)^2 )
VAR Den = SUM( Samples[Weight] )
VAR WVar = DIVIDE( Num, Den )
RETURN SQRT(WVar)
Edit:
if I understand your new request, the Weight is the number of rows with the same Set Value, that is to be used for each of the Actual Value. Then, since there are two pairs of columns, I assume that the requirement is to have a set of measures per each couple of columns.
The formula requires to add a count of the number of rows per each group of Set Value, to be used as weight. I imported the sample table as table "V"
Weighted average for Set Value 1 and Actual Value 1
WAvg1 =
VAR Num =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 1] ) ) * V[Actual Value 1]
)
VAR Den =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 1] ) )
)
RETURN
DIVIDE( Num, Den )
Weighted average for Set Value 2 and Actual Value 2
WAvg2 =
VAR Num =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 2] ) ) * V[Actual Value 2]
)
VAR Den =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 2] ) )
)
RETURN
DIVIDE( Num, Den )
Weighted standard deviation for Set Value 1 and Actual Value 1
WStdDev1 =
VAR Num =
SUMX(
ALL( V ),
VAR WAvg = [WAvg1]
RETURN
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 1] ) ) * ( V[Actual Value 1] - WAvg ) ^ 2
)
VAR Den =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 1] ) )
)
VAR WVariance =
DIVIDE( Num, Den )
RETURN
SQRT( WVariance )
Weighted standard deviation for Set Value 2 and Actual Value 2
WStdDev2 =
VAR Num =
SUMX(
ALL( V ),
VAR WAvg = [WAvg2]
RETURN
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 2] ) ) * ( V[Actual Value 2] - WAvg ) ^ 2
)
VAR Den =
SUMX(
ALL( V ),
CALCULATE( COUNTROWS( V ), ALLEXCEPT( V, V[Set Value 2] ) )
)
VAR WVariance =
DIVIDE( Num, Den )
RETURN
SQRT( WVariance )
Applying these formulas to the sample table we get these results