Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.
Register now!To celebrate FabCon Vienna, we are offering 50% off select exams. Ends October 3rd. Request your discount now.
Hi,
I have 2 tables :
Stock :
Code | team |
1108 | Team1 |
1109 | Team1 |
1113 | Team1 |
1114 | Team1 |
1115 | Team1 |
1116 | Team1 |
1117 | Team1 |
1123 | Team1 |
1124 | Team1 |
1125 | Team1 |
1127 | Team1 |
1128 | Team1 |
1129 | Team1 |
1130 | Team1 |
1131 | Team1 |
1132 | Team1 |
1133 | Team1 |
1134 | Team1 |
1136 | Team2 |
1137 | Team2 |
1138 | Team2 |
1139 | Team2 |
1140 | Team2 |
1145 | Team2 |
1149 | Team2 |
1150 | Team2 |
1151 | Team2 |
1152 | Team2 |
1153 | Team2 |
1154 | Team2 |
1155 | Team2 |
18 | Team2 |
180 | Team2 |
1853 | Team2 |
1877 | Team2 |
1879 | Team2 |
Used:
Code | Team | Sub_team |
1108 | Team1 | Sub_team1 |
1109 | Team1 | Sub_team1 |
1113 | Team1 | Sub_team1 |
1114 | Team1 | Sub_team2 |
1115 | Team1 | Sub_team2 |
1116 | Team1 | Sub_team2 |
1117 | Team1 | Sub_team2 |
1123 | Team1 | Sub_team2 |
1124 | Team1 | Sub_team2 |
1125 | Team1 | Sub_team2 |
1127 | Team1 | Sub_team2 |
1128 | Team1 | Sub_team2 |
1129 | Team1 | Sub_team2 |
1130 | Team1 | Sub_team3 |
1131 | Team1 | Sub_team3 |
1132 | Team1 | Sub_team3 |
1133 | Team1 | Sub_team3 |
1134 | Team1 | Sub_team3 |
1136 | Team2 | Sub_team4 |
1137 | Team2 | Sub_team4 |
1138 | Team2 | Sub_team4 |
1139 | Team2 | Sub_team4 |
1140 | Team2 | Sub_team4 |
1145 | Team2 | Sub_team4 |
1149 | Team2 | Sub_team5 |
1150 | Team2 | Sub_team5 |
1151 | Team2 | Sub_team5 |
1152 | Team2 | Sub_team5 |
1153 | Team2 | Sub_team5 |
1154 | Team2 | Sub_team5 |
1155 | Team2 | Sub_team5 |
1156 | Team2 | Sub_team5 |
1157 | Team2 | Sub_team5 |
1158 | Team2 | Sub_team5 |
I would like to create a matrix to compare the code used and stocked as below :
The 2 tables can have many to many relationship between the codes.
The same code can be in different teams.
Team | Used | Stock | Overused | Overstock | |||
Team1 | |||||||
sub_team1 | 4 | 4 | 0 | 0 | |||
1108 | |||||||
1109 | |||||||
1113 | |||||||
1114 | |||||||
9 | 9 | 0 | 0 | ||||
sub_team2 | 1115 | ||||||
1116 | |||||||
1117 | |||||||
1123 | |||||||
1124 | |||||||
1125 | |||||||
1127 | |||||||
1128 | |||||||
1129 | |||||||
sub_team3 | 5 | 5 | 0 | 0 | |||
1130 | |||||||
1131 | |||||||
1132 | |||||||
1133 | |||||||
1134 | |||||||
Team2 | |||||||
sub_team4 | 6 | 6 | 0 | 0 | |||
1136 | |||||||
1137 | |||||||
1138 | |||||||
1139 | |||||||
1140 | |||||||
1145 | |||||||
sub_team5 | 10 | 7 | 3 | 0 | |||
1149 | |||||||
1150 | |||||||
1151 | |||||||
1152 | |||||||
1153 | |||||||
1154 | |||||||
1155 | |||||||
1156 | |||||||
1157 | |||||||
1158 | |||||||
sub_team6 | 6 | 0 | 6 | 0 | |||
1162 | |||||||
1166 | |||||||
1167 | |||||||
1168 | |||||||
1171 | |||||||
1172 | |||||||
sub_team7 | 6 | 0 | 6 | 0 | |||
1173 | |||||||
1177 | |||||||
1178 | |||||||
1179 | |||||||
1180 | |||||||
1183 | |||||||
0 | 5 | 0 | 5 | ||||
18 | |||||||
180 | |||||||
1853 | |||||||
1877 | |||||||
1879 |
Thank you in advance for your help.
Regards,
Tg
Hi @Anonymous ,
A many-to-many relationship should be avoided where possible, especially for clarity in data modeling. Instead, the approach should be structured with a one-to-many relationship between CodeTable and both Stock and Used.
Start by loading both Stock and Used tables into Power BI. To ensure proper relationships, create a bridge table (CodeTable) containing unique codes:
CodeTable = DISTINCT( UNION( SELECTCOLUMNS(Stock, "Code", Stock[Code]), SELECTCOLUMNS(Used, "Code", Used[Code]) ) )
Then, establish one-to-many relationships:
CodeTable[Code] → Stock[Code]
CodeTable[Code] → Used[Code]
This setup ensures that filtering through CodeTable affects both Stock and Used tables correctly.
Now, create DAX measures to calculate the required values for the matrix. The Used Count measure counts how many times each code appears in the Used table:
Used Count = COUNTROWS(Used)
Similarly, the Stock Count measure calculates the occurrences of each code in the Stock table:
Overused = MAX(0, [Used Count] - [Stock Count])
For overstocked items (codes stocked more than used), reverse the calculation:
Overstock = MAX(0, [Stock Count] - [Used Count])
To ensure that the team and sub-team filtering is respected, use CALCULATE to keep the necessary context:
Used Count by Team = CALCULATE( COUNTROWS( Used ), ALLEXCEPT( Used, Used[Team], Used[Sub_team], Used[Code] ) )
Similarly, apply the same logic for the stock count:
Stock Count by Team = CALCULATE( COUNTROWS( Stock ), ALLEXCEPT( Stock, Stock[Team], Stock[Code] ) )
Use these team-based calculations to ensure that Overused and Overstock calculations remain accurate:
Overused by Team = MAX(0, [Used Count by Team] - [Stock Count by Team])
Overstock by Team = MAX(0, [Stock Count by Team] - [Used Count by Team])
Finally, in the matrix visual, set:
Rows: Team → Sub_team → Code
Values: Used Count, Stock Count, Overused, Overstock
This structure correctly compares used and stocked codes, highlights any overuse or overstock situations, and avoids unnecessary many-to-many relationships.
Hello,
Thank you for your detailed reply.
Here is the matrix, I can't have a good list of vlan in each team and sub-team. Could you please have any susggestion ?
Thank you.