Skip to main content
cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

Calling all Data Engineers! Fabric Data Engineer (Exam DP-700) live sessions are back! Starting October 16th. Sign up.

Reply
Anonymous
Not applicable

Weighted Average Cost where levels of granularity exist between multiple tables

I have a data model that looks like this.

ibesmond_0-1644865345883.png

The two lower tables are connected with using a one-to-many relationship with the field called Agreement ID.

 

I have two levels of granularity in both lower tables, however they are not the same things.  The load table's lowest level of granularity is the load, and the cost table's lowest level of granularity is the cost group.

 

Here I show the contents of both tables.  I want to be able to calculate the total cost, average cost, and most importantly the weighted average cost. 

As you can see, Agreement 1, Load 1 needs to be calculated against the three Cost Groups of Agreement 1.

and so forth.  Ultimately ending with Agreement 2, Load 3 being calculated against the four Cost Croups of Agreement 2.

ibesmond_1-1644865516007.png

 

Summarizing it would like like this:

ibesmond_2-1644865795347.png

Hard pasted to avoid having to create data.

 

 

Agreement ID
LoadVolumeCost GroupCostFormulaExtended Cost Weighted Avg
1150A$4.8050*4.80$240.00 $0.54
1150B$7.2050*7.20$360.00 $0.81
1150C$2.0650*2.06$103.00 $0.23
1275A$4.8075*4.80$360.00 $0.81
1275B$7.2075*4.80$540.00 $1.21
1275C$2.0675*4.80$154.50 $0.35
13100A$4.80100*4.80$480.00 $1.08
13100B$7.20100*4.80$720.00 $1.62
13100C$2.06100*4.80$206.00 $0.46
2140A$5.6040*5.60$224.00 $0.50
2140B$8.1240*8.120$324.80 $0.73
2140C$1.5040*1.50$60.00 $0.13
2140D$6.3440*6.340$253.60 $1.15
22100A$5.60100*5.60$560.00 $1.26
22100B$8.12100*8.120$812.00 $1.82
22100C$1.50100*1.50$150.00 $0.34
22100D$6.34100*6.340$634.00 $2.88
2380A$5.6080*5.60$448.00 $1.01
2380B$8.1280*8.120$649.60 $1.46
2380C$1.5080*1.50$120.00 $0.27
2380D$6.3480*6.340$507.20 $2.31
         
 Sum1555  Sum$7,906.70 $20.97
     Average$376.51  
         
 Cost GroupVolumeCost GroupAverageWeighted AvgExt. Weighted  
 A445A$5.20$5.20$385.33  
 B445B$7.66$7.65$132.25  
 C395C$1.78$1.78$518.56  
 D180D$6.34$6.34$215.50  

 

This is what it would look breoken down.

 

ibesmond_4-1644866179930.png

 

Agreement IDLoadVolumeCost GroupCostFormulaExtended CostWeighted Average
1150A$4.8050*4.80$240.00$0.54
1275A$4.8075*4.80$360.00$0.81
13100A$4.80100*4.80$480.00$1.08
2140A$5.6040*5.60$224.00$0.50
22100A$5.60100*5.60$560.00$1.26
2380A$5.6080*5.60$448.00$1.01
       $5.20
        
Agreement IDLoadVolumeCost GroupCostFormulaExtended CostWeighted Average
1150B$7.2050*7.20$360.00$0.81
1275B$7.2075*4.80$540.00$1.21
13100B$7.20100*4.80$720.00$1.62
2140B$8.1240*8.120$324.80$0.73
22100B$8.12100*8.120$812.00$1.82
2380B$8.1280*8.120$649.60$1.46
       $7.65
        
Agreement IDLoadVolumeCost GroupCostFormulaExtended CostWeighted Average
1150C$2.0650*2.06$103.00$0.23
1275C$2.0675*4.80$154.50$0.35
13100C$2.06100*4.80$206.00$0.46
2140C$1.5040*1.50$60.00$0.13
22100C$1.50100*1.50$150.00$0.34
2380C$1.5080*1.50$120.00$0.27
       $1.78
        
Agreement IDLoadVolumeCost GroupCostFormulaExtended CostWeighted Average
2140D$6.3440*6.340$253.60$1.15
22100D$6.34100*6.340$634.00$2.88
2380D$6.3480*6.340$507.20$2.31
       $6.34

 

So there are two issues that I am having and need help with.

 

First, in Power BI I create a table and bring in Agreement ID from the Agreement table.

Then I bring in The Load and Volume Columns from the Load table.

Then when I try to bring in the Cost Group from the Cost table it errs

ibesmond_5-1644866869963.png

 

The second problem I have is writing the DAX expression to get the weighted average cost.

WAC = Cost * ( Volume / Total Volume)

The only problem is my cost is in one table and my volume is in the other table, and PBI can't determine the relationship between these fields either.

 

I was thinking, I might be able to summarize the volume to get rid of the load level details, but I would still have the cost groups with worry about.  Any ideas. Thank you.

2 REPLIES 2
Jos_Woolley
Solution Sage
Solution Sage

Hi,

Sounds like the relationship between Cost and Agreement is unidirectional. You'll need to change it to bidirectional.

For your measure, try:

WAC =
DIVIDE(
    SUM( Cost[Cost] ) * SUM( Load[Volume] ),
    CALCULATE( SUM( Load[Volume] ), ALL() )
)

Regards

 

technolog
Super User
Super User

Why the table visual breaks
Agreement is a dimension. Load and Cost are both many side tables at different grains. When you drop Load and Cost Group into the same table, Power BI would need to materialize an N by M join inside each Agreement. That join does not exist in the model, so the visual throws the cannot determine the relationship error. The diagram on page two shows exactly this shape Agreement in the middle with separate one to many links to Load and to Cost.

How to show rows like Load by Cost Group
Either do not put both child tables in the same visual and drive everything with measures, or create a calculated table that explicitly builds the product per Agreement. Example for a calc table

LOAD COST
VAR vLoad =
SUMMARIZE( Load, Agreement[Agreement ID], Load[Load], "Volume", SUM( Load[Volume] ) )
VAR vCost =
SUMMARIZE( Cost, Agreement[Agreement ID], Cost[Cost Group], "Cost", MAX( Cost[Cost] ) )
RETURN
NATURALINNERJOIN( vLoad, vCost )

Use this table for row level visuals only. Keep the relationships from Agreement to both original facts single direction. This avoids ambiguous paths and keeps calculations predictable.

Weighted cost measures that work with the original two fact tables
The safest pattern is to aggregate each table to the Agreement grain, join them virtually inside a measure, and then compute totals and averages.

Total Extended Cost
VAR VolByAgreement =
SUMMARIZE( Load, Agreement[Agreement ID], "Vol", SUM( Load[Volume] ) )
VAR CostByAgreementGroup =
SUMMARIZE( Cost, Agreement[Agreement ID], Cost[Cost Group], "Cost", MAX( Cost[Cost] ) )
VAR J = NATURALINNERJOIN( CostByAgreementGroup, VolByAgreement )
RETURN
SUMX( J, [Cost] * [Vol] )

Weighted Average composite cost across all groups
This is the average of the full cost per unit when the group components are additive.

WAC total
DIVIDE( [Total Extended Cost], SUM( Load[Volume] ) )

Weighted Average by a selected Cost Group
Denominator uses only the Agreements where that group exists. This reproduces the per group numbers shown in the screenshots page three and page four.

WAC by group
VAR VolByAgreement =
SUMMARIZE( Load, Agreement[Agreement ID], "Vol", SUM( Load[Volume] ) )
VAR ThisGroupCosts =
SUMMARIZE(
FILTER( Cost, Cost[Cost Group] = SELECTEDVALUE( Cost[Cost Group] ) ),
Agreement[Agreement ID],
"Cost", MAX( Cost[Cost] )
)
VAR J = NATURALINNERJOIN( ThisGroupCosts, VolByAgreement )
RETURN
DIVIDE( SUMX( J, [Vol] * [Cost] ), SUMX( J, [Vol] ) )

If you also want the sum of all group level weighted averages as a single figure

WAC sum of groups
SUMX( VALUES( Cost[Cost Group] ), [WAC by group] )

About bi directional filters
Turning the Agreement to Cost relationship to bidirectional will let filters flow between the two fact tables and can make a simple table work, and a short answer on the forum suggests exactly that together with a compact measure

WAC
DIVIDE(
SUM( Cost[Cost] ) * SUM( Load[Volume] ),
CALCULATE( SUM( Load[Volume] ), ALL() )
)

Helpful resources

Announcements
November Fabric Update Carousel

Fabric Monthly Update - November 2025

Check out the November 2025 Fabric update to learn about new features.

Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Users online (25)