# Power BI Divide by distinct value for a group by - powerbi

Table1
Region
Subregion
DataID
Amount
North Central
Missouri
12042022
123000
North Central
Minnesota
12052022
170000
North Central
North Dakota
10042022
234000
Northeast
New York
08042022
500000
Northeast
New Jersey
12052022
578000
Southwest
Nevada
12032022
679000
Southwest
Arizona
10032022
654000
DimDate
DataID
Period
NumofWeeks
12052022
2022_05
5
10042022
2022_04
4
12042022
2022_04
4
12052022
2022_05
5
08042022
2022_04
4
12032022
2022_03
4
10032022
2022_03
4
I want to Divide the count of records per region by NumofWeeks
I tried
Divide per region week = MROUND(DIVIDE(COUNT('table1'[Region]), DISTINCT(DimDate[NumofWeeks])),1)
Works but only if I filter the Matrix by just one Period for more I have the message
A table of multiple values was supplied where a single value was expected
I appreciate your help Thank you

IF you have unique DimDate[Period]-DimDate[NumofWeeks] linked values then you can try this suggetion.
Divide per region week =
VAR TotalCountPerRegion = CountRows('Table1')
VAR tblNumOfWeeksInPeriod=
SUMMARIZE(
DimDate
,DimDate[Period]
,DimDate[NumofWeeks]
)
VAR SuMOfWeeksInPeriod = SUMX(tblNumOfWeeksInPeriod,DimDate[NumofWeeks])
RETURN
MROUND(
DIVIDE(
TotalCountPerRegion
,SuMOfWeeksInPeriod
)
,1
)

Related

Nested DAX iteration with multiple conditions

I am hopeful you will be able to help me or point me in the right direction to work out a DAX formula to return a calculated table.
I have spend hours trying to figure it out but but have hit a wall and cannot move further.
For the purpose of this illustration, I have a simple table which contains orders. Customer can purchase an order from two different shops. I am trying to work out which are the order numbers of red products which have been purchased before the max expiry date of a yellow product, if sold to the same customer at the same shop.
My table is as follows:
Order ID Office Customer Order Date Expiry Date Product
1 Shop1 Cust1 02/02/2022 27/08/2022 Red
2 Shop1 Cust1 15/06/2021 04/02/2022 Red
3 Shop1 Cust1 30/09/2022 29/04/2023 Blue
4 Shop1 Cust1 07/05/2021 18/12/2021 Yellow
5 Shop1 Cust2 30/05/2021 23/05/2022 Red
6 Shop2 Cust2 08/02/2022 13/01/2023 Yellow
7 Shop1 Cust2 03/09/2022 13/04/2023 Blue
8 Shop1 Cust3 24/04/2021 11/07/2021 Yellow
9 Shop1 Cust3 23/02/2022 21/01/2023 Yellow
10 Shop1 Cust3 03/06/2022 24/11/2022 Blue
11 Shop1 Cust3 04/09/2021 28/08/2022 Red
12 Shop1 Cust3 05/09/2021 28/08/2022 Red
The desired output of the calculated table is as follows:
Order ID
2
11
12
As explained, I need to retrieve all the order IDs for the red product purchased by the same customer who has also purchased a yellow product at the same shop as the red product and where the max expiry date of the yellow product is after the order date of the red product.
My table has the following Red products and here is the explanation why they should/shouldn't be included:
Order ID 1 - Don't flag this as max expiry date of Yellow product (order #4 - 18/12/21) is before the order date of Red product (order #1 - 02/02/22)
Order ID 2 - Flag this as max expiry date of the Yellow product (order #4 - 18/12/21) is after the order date of Red product (order #2 - 15/06/21)
Order ID 5 - Don't flag it as the Yellow product (order #6) was sold in a different Shop as Red product (there is no max expiry date of Yellow product in the same shop as the Red product order #5)
Order ID 11 - Flag this as the max expiry date of Yellow product (order #9) is after the order date of Red product (order #11)
Order ID 12 - Flag this as the max expiry date of Yellow product (order #9) is after the order date of Red product (order #12)
Hope the above example is clear.
Your advice how to achieve this will be greatly appreciated.
One of possible solution:
Table =
var redproducts = CALCULATETABLE(Orders, Orders[Product] ="Red")
var yellowproducts = SELECTCOLUMNS(CALCULATETABLE(Orders, Orders[Product] = "Yellow"), "YellowCust", [Customer], "YellowStore", [Office], "YellowExpiration", [Expiry Date])
return GENERATE(redproducts, FILTER(yellowproducts, [Customer] = [YellowCust] && [Office] = [YellowStore] && [Order Date] < [YellowExpiration]))
of course, you can select only ID at the end;
Alternative:
=
FILTER(
ADDCOLUMNS(
'Table',
"Yellow Count",
VAR Office = 'Table'[Office]
VAR Customer = 'Table'[Customer]
RETURN
CALCULATE(
MAX( 'Table'[Expiry Date] ),
FILTER(
'Table',
'Table'[Office] = Office
&& 'Table'[Customer] = Customer
&& 'Table'[Product] = "Yellow"
)
)
),
'Table'[Product] = "Red"
&& [Yellow Count] > 'Table'[Order Date]
)

Creating a DAX Measure to count where a subgroup is greater than 1

I have a dataset with multiple user logins and multiple districts as follows:
User
District
Region
UserA
HKG
China
UserA
PRG
Europe
UserA
CKG
China
UserB
LHR
Europe
UserB
AMS
Europe
UserB
TYO
Japan
UserA
CKG
China
UserC
SYD
Australia
UserC
MEL
Australia
UserD
SYD
Australia
UserD
MEL
Australia
I want to see the count of users that have logged into more than a single district within a region
Region
Created Measure
China
1
Europe
1
Japan
0
Australia
2
China has 1, because only UserA has logged into multiple China Districts
Europe has 1, because only UserB has logged into multiple Europe Districts
Japan has 0, because no user has logged into more than 1 Japan District
Australia has 2, because both User C & D have logged onto multiple Australia Districts
I have gotten close with creating a table, but I can only seem to get it to count the distinct values, not the values where the aggregate is greater than 1. This is the DAX I have so far:
DEFINE
TABLE UserGroup =
SUMMARIZECOLUMNS (
User[User],
User[Branch],
User[Region],
"UserCount", COUNT('User'[User]),
"User Distinct Count", DISTINCTCOUNT('User'[User])
)
EVALUATE
GROUPBY(
UserGroup,
UserGroup[Region],
"Failing Formula", SUMX(CURRENTGROUP(), [User Distinct Count])
)
EVALUATE
VAR allValTbl= -- DISTINCT(tbl)
SUMMARIZE(
tbl
,tbl[Region]
,tbl[District]
,tbl[User]
)
VAR moreThenOne=
FILTER(
allValTbl
,CALCULATE(COUNTROWS(tbl))>1
)
RETURN
ADDCOLUMNS(
VALUES(tbl[Region])
,"#DCount",VAR currReg = [Region]
RETURN
COUNTROWS(
FILTER(
moreThenOne
,[Region]=currReg
)
)+0
)

How to group by on Power BI using DAX

I have two tables in Power BI as follows:
COUNTRIES
COD COUNTRY
1 BRAZIL
2 ARGENTINA
3 CHILE
4 BRASIL
5 COLOMBIA
6 ARGENTINA
7 URUGUAI
SALES
COD DATE
1 2021-01-02
2 2021-10-01
3 2019-09-04
1 2018-07-05
7 2019-04-10
There's a relationship between the two tables, on the COD column.
I need to count how many countries (column "COUNTRY" from the table "COUNTRIES") have a status CHURN. It's considered CHURN when their latest order from the table "SALES" is more than 180 days, using today as a reference.
I know that I need to group by the MAX date per country, do a DATEDIFF, and then do a COUNT. I've tried using ALL and SUMMARIZE, but I haven't found a way to solve this problem.
Are you able to add a calculated column to store the max sales date for each country in your COUNTRIES table? Either in Power BI or directly in your database. If so, here's one solution with 2 steps.
Create a MaxSalesDate column in your COUNTRIES table. DAX for a calculated column below:
MaxSalesDate =
VAR COD = COUNTRIES[COD]
RETURN MAXX(FILTER(SALES, SALES[COD] = COD), SALES[DATE])
Create a measure that counts the number of MaxSalesDate values that are older than 180 days old:
CountCHURN = COUNTX(COUNTRIES, IF(DATEDIFF(COUNTRIES[MaxSalesDate], TODAY(), Day) > 180, 1))

How to remove or exclude rows from a table using date slicer selection?

As per the below scenario,I need to exclude all the rows in the table Sales with columns Client,sales,salesdate and region which fall outside the selected maximum and minimum date range of the date slider.
Could anyone please suggest a DAX , I will share my DAX query which is not working.I tried to search official guides in PowerBI for selectedValues() to handle this date filter condition but nothing seems to be working.
I created a Calendar table with distinct values of the dates as present in the Sales Dates column of the Sales table. There is no relationship between these two tables. I used the below DAX measures to handle the filtering criteria for excluding the rows:-
Below measures are meant to find maximum and minimum dates in the selection slider
MaxDate=MAX(DateDimention[Dates])
MinDate=MIN(DateDimention[Dates])
Below ExcludedMeasure is meant to set 1 flag to the values other than selected values which are selected for both min and max dates.
I dragged and dropped it in the visual filter of my table Sales and set it to dont show.But it seems to be not working.
Please suggest how can I fix it.
ExcludeMeasure = IF (SELECTEDVALUE(Calendar,Calendar[MinDate],0,1),
IF (SELECTEDVALUE(Calendar,Calendar[MaxDate],0,1)
My Present Visualization and independent Calendar table to be used in the filter slider:-
Present visualization
Independent Calendar Table
Input data source [Excel]
Client Sales SalesDates Region
A 1000 1.1.2000 USA
A 100 1.2.2000 USA
A 200 4.3.2000 USA
B 110 4.3.2000 Europe
B 1000 5.4.2000 Europe
B 200 6.8.2001 Europe
C 1100 7.9.2001 Asia
C 2000 8.12.2001 Asia
D 100 1.2.2002 Australia
D 1300 6.3.2002 Australia
E 100 7.5.2002 Africa
Expected Results :
If I select Minimum slider date as 01.04.2001 and maximum slider date as 1.09.2001 in my[Dates] filter visualization, then it should return the below results after excluding '5.4.2001' and '6.8.2001':-
Client Sales SalesDates Region
A 1000 1.1.2000 USA
A 100 1.2.2000 USA
A 200 4.3.2000 USA
B 110 4.3.2000 Europe
C 1100 7.9.2001 Asia
C 2000 8.12.2001 Asia
D 100 1.2.2002 Australia
D 1300 6.3.2002 Australia
E 100 7.5.2002 Africa
Kind regards
Sameer
A relationship between the date table and the sales table would be ideal, as when you filter the date from the date table, the filter would exclude the records from the sale tables.
If you can't have a date table with the relationship, your exclude measure needs to be something like this:
Exclude =
CALCULATE(COUNT(Sales[Id]),
Sales[SalesDates] >= [MinDate] &&
Sales[SalesDate] <= [MaxDate]) > 0

Power BI DAX Avg of AVG

I want the results to show, for example:
AVG GROUP 1 takes the avg of the brand then avg's the group. So,
avg BRAND J = 8.4
avg BRAND K = 4.8
avg BRAND L = 4.9
AVG GROUP 1 would then = 6.03 NOT 6.6
This would then continue for all groups.
Thanks
DataTable
GROUP BRAND PERCENT CHANGE
GROUP 1 BRAND J 4.8%
GROUP 1 BRAND J 12.0%
GROUP 1 BRAND K 4.8%
GROUP 1 BRAND L 4.9%
GROUP 2 BRAND M 8.0%
GROUP 3 BRAND A 4.0%
GROUP 4 BRAND B 8.0%
GROUP 4 BRAND B 15.0%
GROUP 4 BRAND C 8.0%
GROUP 4 BRAND N 7.0%
GROUP 5 BRAND D 5.0%
GROUP 5 BRAND E 4.0%
GROUP 5 BRAND E 6.0%
GROUP 5 BRAND E 6.0%
Create a measure:
Group Average =
AVERAGEX (
SUMMARIZE (
Data,
Data[Group],
Data[Brand],
"Brand Average", AVERAGE ( Data[Percent Change] )
),
[Brand Average]
)
where "Data" is your table name.
Result:
More detailed result:
How it works:
First, we summarize your data by Group and Brand, and calculate average per each. Then, we use AVERAGEX to iterate the summarized table, and calculate the average of the averages.
Edit:
To filter out groups with 1 brand, modify the measure:
Group Average =
AVERAGEX(
SUMMARIZE (
Data,
Data[Group],
Data[Brand],
"Brand Average", AVERAGE ( Data[Percent Change] ),
"Brand Count", CALCULATE(COUNT(Data[BRAND]), ALLEXCEPT(Data, Data[GROUP])),
IF([Brand Count] > 1, [Brand Average])
)
You will get: