Filter by two dimension combinations - powerbi

My (heavily simplified) data model contains of:
a fact table with FTE values and two foreign keys for 'Country' and 'Process'
two dimension tables for 'Country' and 'Process' with relationships to the fact table
I also have a table of combinations of 'Country' and 'Process' that I want to filter my data on:
Country Process Country-Process
= = = = = = = = = = = = = = = = = = = =
France process 1 France process 1
France process 2 France process 2
Australia process 1 Australia process 1
Australia process 3 Australia process 3
USA process 2 USA process 2
USA process 3 USA process 3
The goals is to filter my FTE, to show only FTE for these country-process combinations. However, it is not possible to have the Combinations table filter both Country and Process tables through relationships.
If I filter on Country, I get all processes for those countries. If I filter on Process, I get all countries for those processes. If I filter on these countries (there are more) and these processes (there are more), I get all these processes for all these countries. But I just want the combinations listed.
I have succeeded in making a measure with a SUMX on a virtual table that only contains the listed combinations (works in DAX Studio), but the Entity relationship somehow got lost and all countries showed the aggregated value per process.
The measure is set-up as follows:
SUMX(
FILTER(
CROSSJOIN(
ADDCOLUMS(
CROSSJOIN(VALUES(Country[country]), VALUES(Process[process]) ),
"Country_Process", Country[country] & " " & Process[process]
),
VALUES(Combination[Country-Process]
),
[Country_Process] = Combinations[Country-Process]
),
[FTE]
)
Help is much appreciated!

Assuming your tables and relationships look like this:
Combinations
Country
Process
France
Process 1
France
Process 2
Australia
Process 1
Australia
Process 3
USA
Process 2
USA
Process 3
Countries
Country
France
Australia
USA
Process
Process
Process 1
Process 2
Process 3
FTE
ID
Country
Process
15
Australia
Process 3
3
Australia
Process 1
5
Australia
Process 3
11
Australia
Process 3
13
France
Process 3
14
France
Process 2
12
France
Process 1
1
France
Process 1
7
France
Process 3
8
France
Process 2
2
USA
Process 3
4
USA
Process 3
6
USA
Process 1
9
USA
Process 3
10
USA
Process 1
Relationships
DAX Calculation:
You can use TREATAS to create a virtual relationship. The measure can be either a visual column or a filter in the table.
Filter FTE =
CALCULATE (
COUNTROWS ( FTE ),
TREATAS (
SUMMARIZE ( Combinations, Combinations[Country], Combinations[Process] ),
FTE[Country],
FTE[Process]
)
)
Output

Related

Latest values by category based on a selected date

First, as I am a French guy, I want to apologise in advance for my poor English!
Despite my searches since few days, I cannot find the correct measure to solve my problem.
I think I am close to the solution, but I really need help to achieve this job!
Here is my need:
I have a dataset with a date table and a "Position" (i.e. "stock") table, which is my fact table, with date column.
Classic relationship between these 2 tables. Many Dates in "Position" table / 1 date un "Dates" table.
My "Dates" table has a one date per day (Column "AsOf")
My "Deals" table looks like this:
Id
DealId
AsOfDate
Notional
10000
1
9/1/2022
2000000
10001
1
9/1/2022
3000000
10002
1
9/1/2022
1818147
10010
4
5/31/2022
2000000
10011
4
5/31/2022
997500
10012
4
5/31/2022
1500000
10013
4
5/31/2022
1127820
10014
5
7/27/2022
140000
10015
5
7/27/2022
210000
10016
5
7/27/2022
500000
10017
5
7/27/2022
750000
10018
5
7/27/2022
625000
10019
1
8/31/2022
2000000
10020
1
8/31/2022
3000000
10021
1
8/31/2022
1801257
10022
1
8/31/2022
96976
10023
1
8/31/2022
1193365
10024
1
8/31/2022
67883
Based on a selected date (slicer with all dates from "Dates" table), I would like to calculate the sum of Last Notional for each "Deal" (column "DealId").
So, I must identify, for each Deal, the last "Asof Date" before or equal to the selected date and sum all matching rows.
Examples:
If selected date is 9/1/2022, I will see all rows, except rows asof date = 8/31/2022 for deal 1 (as the last date for this deal is 9/1/2022).
So, I expect to see:
DealId Sum of Notional
1 6 818 147
4 5 625 320
5 2 225 000
Grand Total 14 668 467
If I select 8/31/2022, total for Deal 1 changes (as we now take rows of 8/31 instead of 1/9):
DealId Sum of Notional
1 8 159 481
4 5 625 320
5 2 225 000
Grand Total 16 009 800
If I select 7/29, only deals 4 and 5 are active on this date, so the results should be:
DealId Sum of Notional
4 5 625 320
5 2 225 000
Grand Total 7 850 320
I think I found a solution for the rows, but my total is wrong (only notionals of the selected date are totalized).
I also think my measure is incorrect if I try to display the notional amounts aggregated by Rating (other column in my table) instead of deal.
Here is my measure:
Last Notional =
VAR SelectedAsOf =
SELECTEDVALUE ( Dates[AsOf] )
VAR LastAsofPerDeal =
CALCULATE (
MAX ( Deals[AsOf Date] ),
FILTER ( ALLEXCEPT ( Deals, Deals[DealId] ), Deals[AsOf Date] <= SelectedAsOf )
)
RETURN
CALCULATE (
SUM ( Deals[Notional] ),
FILTER (
ALLEXCEPT ( Deals, Deals[DealId]),
LastAsofPerDeal = Deals[AsOf Date]
)
)
I hope it is clear for you, and you will be able to find a solution for this.
Thanks in advance.
Antoine
Make sure you have no relationship between your calendar table and deals table like so.
Create a slicer with your dates table and create a table visual with deal id. Then add a measure to the table as follows:
Sum of Notional =
VAR slicer = SELECTEDVALUE(Dates[Date])
VAR tbl = FILTER(Deals,Deals[AsOfDate] <= slicer)
VAR maxBalanceDate = CALCULATE(MAX(Deals[AsOfDate]),tbl)
RETURN
CALCULATE(
SUM(Deals[Notional]),
Deals[AsOfDate] = maxBalanceDate
)

DAX measure for Sum of values on the first and last day of a cycle

I have a table 'fact WorkItems', where changes made to items are saved on the day of the change ([ChangedDate]).
WorkItemId
AreaPath
ChangedDate
State
StoryPoints
IterationPath
1day
14day
Commitment
Delivered
1
A
04/01/2022
New
4
24.1
4
1
A
06/01/2022
Ready
6
24.1
6
1
A
10/01/2022
Active
6
24.1
6
1
A
12/01/2022
Testing
8
24.1
8
8
1
A
18/01/2022
Testing
2
24.1
1
A
19/01/2022
Testing
2
24.1
1
A
28/01/2022
Closed
2
24.1
2
1
A
01/02/2022
Closed
2
24.1
2
2
1
A
03/02/2022
Closed
2
24.1
I also have a table called 'dim Itrations', where cycles' start and end dates are kept.
IterationPath
StartDate
EndDate
24.1
13/01/2022
02/02/2022
24.2
03/02/2022
17/02/2022
24.3
18/02/2022
04/03/2022
I have created a measure [1day] which tells me how many [StoryPoints] had an Item on or before a cycle started
1day =
CALCULATE (
SUM( 'fact WorkItems'[StoryPoints] ),
FILTER (
'dim Iterations',
MAX('fact Workitems'[ChangedDate]) <= 'dim Iterations'[StartDate]
)
)
I have also created a measure [14day] which tells me how many [StoryPoints] had an Item by the end of the cycle once it's in "Closed" [State].
14day =
CALCULATE (
SUM( 'fact WorkItems'[StoryPoints] ),
FILTER ('fact WorkItems',
AND(
'fact Workitems'[State]="Closed",
'fact Workitems'[ChangedDate] <= MIN('dim Iterations'[EndDate])
)
))
My objective is to create two measures: [Commitment] and [Delivered] which will sum all the StoryPoints each team ([AreaPath]) had for each of  the cycles exactly on the the day the cycle started and ended (the latter with status closed). I know how to "tell" Power BI to only look at the rows, where Change date = [StartDate] or [ClosedDate].
The problem is when changes to items are made before the start/end date. I'm trying to "fill in those gaps" in the table by telling Power BI to look at the last record which was changed before or on the Start/End Date and to use those values. What I'm trying to achieve is presented in the table. Any ideas?

Power BI Measure to countrows of related values several related tables deep

I need to create a measure for a card that will count the total number of Question Groups that exist for each person using the tables below.
I've tried the following but it's returning the result 10, instead of the expected result which should be 6. (George = 2, Susan = 1, tom = 1, bill=1, sally =1, mark =0, jason=0)
Measure = COUNTROWS(NATURALLEFTOUTERJOIN(NATURALLEFTOUTERJOIN(People,Questions),'Question Groups'))
What am I doing wrong?
Table: People
PeopleID
Name
1
George
2
Susan
3
Tom
4
Bill
5
Sally
6
Mark
7
Jason
Table: relPeopleQuestions
PeopleID
QuestionID
1
1
1
2
1
3
2
4
2
5
3
6
4
7
5
8
Table: Questions
Question ID
Question name
Questiong Group ID
1
How are you?
1
2
Favorite Color?
2
3
Favorite Movie?
2
4
Sister's Name
3
5
Brother's Name
3
6
What is your birthdate?
1
7
What City do you live in?
1
8
Favorite game?
2
Table: Question Groups
Question Group ID
Question Group Name
1
Assorted
2
Favorites
3
Relatives
A working example file can be obtained here.
A distinct count on the Question Group ID from the Questions table would seem to be sufficient, e.g.
MyMeasure =
VAR MyTable =
SUMMARIZE (
People,
People[Name],
"Count", DISTINCTCOUNT ( Questions[Question Group ID] )
)
RETURN
SUMX ( MyTable, [Count] )

Power BI DAX Measure works for one column but not another

Using the information below I need to create a new table in DAX called Table (Download a demo file here).
I need to find the location of each employee (column "Name") at the time of the sale date in column "Sale Date" based on their contract details in table DbEmployees. If there is more than one valid contract for a given employee that the sale date fits in, use the shortest contract length.
My problem is that the below measure isn't working to generate column "Location", but it works just fine for column "new value".
Why is this happening and how can it be fixed?
Expected result:
SaleID
EmployeeID
Sale Date
new value
Name
Location
1
45643213
2021-02-04
89067445
Sally Shore
4
2
57647868
2020-04-15
57647868
Paul Bunyon
3
3
89067445
2019-09-24
57647868
Paul Bunyon
6
DbEmployees:
ID
Name
StartDate
EndDate
Location
Position
546465546
Sandra Newman
2021/01/01
2021/12/31
1
Manager
546465546
Sandra Newman
2020/01/01
2020/12/31
2
Clerk
546465546
Sandra Newman
2019/01/01
2019/12/31
3
Clerk
545365743
Paul Bunyon
2021/01/01
2021/12/31
6
Manager
545365743
Paul Bunyon
2020/04/01
2020/05/01
3
Clerk
545365743
Paul Bunyon
2019/04/01
2021/01/01
6
Manager
796423504
Sally Shore
2020/01/01
2020/12/31
4
Clerk
783546053
Jack Tomson
2019/01/01
2019/12/31
2
Manager
DynamicsSales:
SaleID
EmployeeID
Sale Date
1
45643213
2021/02/04
2
57647868
2020/04/15
3
89067445
2019/09/24
DynamicsContacts:
EmployeeID
Name
Email
45643213
Sandra Newman
sandra.newman#hotmail.com
65437658
Jack Tomson
jack.tomson#hotmail.com
57647868
Paul Bunyon
paul.bunyon#hotmail.com
89067445
Sally Shore
sally.shore#hotmail.com
DynamicsAudit:
SaleID
Changed Date
old value
new value
AuditID
Valid Until
1
2019/06/08
65437658
57647868
1
2020-06-07
1
2020/06/07
57647868
89067445
2
2021-05-07
1
2021/05/07
89067445
45643213
3
2021-05-07
2
2019/06/08
65437658
57647868
4
2020-06-07
2
2020/06/07
57647868
89067445
5
2021-05-07
2
2021/05/07
89067445
45643213
6
2021-05-07
3
2019/06/08
65437658
57647868
7
2020-06-07
3
2020/06/07
57647868
89067445
8
2021-05-07
3
2021/05/07
89067445
45643213
9
2021-05-07
From what I can see there are a couple of issues with your formula.
First of all there is no relationship between Table and DbEmployees so when you are filtering exclusively on the dates, which might get you the wrong Location. This can be fixed by changing the formula to:
Location =
VAR CurrentContractDate = [Sale Date]
VAR empName = [Name]
RETURN
VAR RespLocation =
TOPN (
1,
FILTER(DbEmployees, DbEmployees[Name] = empName),
IF (
.....
Secondly, you need to remember that the TOPN function can return multiple rows, from the documentation:
If there is a tie, in order_by values, at the N-th row of the table, then all tied rows are returned. Then, when there are ties at the N-th row the function might return more than n rows.
This can be fixed by picking the Max/Min of the result in the table:
RETURN MAXX(SELECTCOLUMNS( RespLocation,"Location", [Location] ), [Location])
Finally, I don't understand why the last row on the expected result should be a 3, given that the sale date is within a record with location 6.
Full expression:
Location =
VAR CurrentContractDate = [Sale Date]
VAR empName = [Name]
RETURN
VAR RespLocation =
TOPN (
1,
FILTER(DbEmployees, DbEmployees[Name] = empName),
IF (
CurrentContractDate <= DbEmployees[EndDate]
&& CurrentContractDate >= DbEmployees[StartDate], //Check, whether there is matching date
DATEDIFF ( DbEmployees[StartDate], DbEmployees[EndDate], DAY ), //If so, rank matching locations (you may want to employ a different formula)
MIN ( //If the location is not matching, calculate how close it is (from both start and end date)
ABS ( DATEDIFF ( CurrentContractDate, DbEmployees[StartDate], DAY ) ),
ABS ( DATEDIFF ( CurrentContractDate, DbEmployees[EndDate], DAY ) )
) + 1000000 //Add a discriminating factor in case there are matching rows that should be favoured over non-matching.
), 1
)
RETURN
MAXX(SELECTCOLUMNS( RespLocation,"Location", [Location] ), [Location])

Average of percent of column totals in DAX

I have a fact table named meetings containing the following:
- staff
- minutes
- type
I then created a summarized table with the following:
TableA =
SUMMARIZECOLUMNS (
'meetings'[staff]
, 'meetings'[type]
, "SumMinutesByStaffAndType", SUM( 'meetings'[minutes] )
)
This makes a pivot table with staff as rows and columns as types.
For this pivottable I need to calculate each cell as a percent of the column total. For each staff I need the average of their percents. There are only 5 meeting types so I need the sum of these percents divided by 5.
I don't know how to divide one number grouped by two columns by another number grouped by one column. I'm coming from the SQL world so my DAX is terrible and I'm desperate for advice.
I tried creating another summarized table to get the sum of minutes for each type.
TableB =
SUMMARIZECOLUMNS (
'meetings'[type]
, "SumMinutesByType", SUM( 'meetings'[minutes] )
)
From there I want 'TableA'[SumMinutesByStaffAndType] / 'TableB'[SumMinutesByType].
TableC =
SUMMARIZECOLUMNS (
'TableA'[staff],
'TableB'[type],
DIVIDE ( 'TableA'[SumMinutesByType], 'TableB'[SumMinutesByType]
)
"A single value for column 'Minutes' in table 'Min by Staff-Contact' cannot be determined. This can happen when a measure formula refers to a column that contains many values without specifying an aggregation such as min, max, count, or sum to get a single result."
I keep arriving at this error which leads me to believe I'm not going about this the "Power BI way".
I have tried making measures and creating matrices on the reports view. I've tried using the group by feature in the Query Editor. I even tried both measures and aggregate tables. I'm likely overcomplicating it and way off the mark so any help is greatly appreciated.
Here's an example of what I'm trying to do.
## Input/First table
staff minutes type
--------- --------- -----------
Bill 5 TELEPHONE
Bill 10 FACE2FACE
Bill 5 INDIRECT
Bill 5 EMAIL
Bill 10 OTHER
Gary 10 TELEPHONE
Gary 5 EMAIL
Gary 5 OTHER
Madison 20 FACE2FACE
Madison 5 INDIRECT
Madison 15 EMAIL
Rob 5 FACE2FACE
Rob 5 INDIRECT
Rob 20 TELEPHONE
Rob 45 FACE2FACE
## Second table with SUM of minutes, Grand Total is column total.
Row Labels EMAIL FACE2FACE INDIRECT OTHER TELEPHONE
------------- ------- ----------- ---------- ------- -----------
Bill 5 10 5 10 5
Gary 5 5 10
Madison 15 20 5
Rob 50 5 20
Grand Total 25 80 15 15 35
## Third table where each of the above cells is divided by its column total.
Row Labels EMAIL FACE2FACE INDIRECT OTHER TELEPHONE
------------- ------- ----------- ------------- ------------- -------------
Bill 0.2 0.125 0.333333333 0.666666667 0.142857143
Gary 0.2 0 0 0.333333333 0.285714286
Madison 0.6 0.25 0.333333333 0 0
Rob 0 0.625 0.333333333 0 0.571428571
Grand Total 25 80 15 15 35
## Final table with the sum of the rows in the third table divided by 5.
staff AVERAGE
--------- -------------
Bill 29.35714286
Gary 16.38095238
Madison 23.66666667
Rob 30.5952381
Please let me know if I can clarify an aspect.
You can make use of the built in functions like %Row total in Power BI, Please find the snapshot below
If this is not what you are looking for, kindly let me know (I have used your Input table)