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

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
EvinMensler
Regular Visitor

Calculating expression based on related tables

Hi.

I have a table with the forecast quantity of some products and another one with their ingredients and ratios.

Now i can get the needed ingredient quantities based on just these two tables; the problem is that some ingredients also have their components and i cant figure out how to calculate the total quantity.

pbi link 

the result:

ingredient_name = Ingredients_list[ingredient_name]

quantity_forecast = CALCULATE(SUM(Forecast[quantity]), SUMMARIZE(Ingredients, Forecast[product_name], Ingredients[ingredient_name]))
ratio_forecast = AVERAGE(Ingredients[ratio])
quantity_ingredients = [quantity_forecast] * [ratio_forecast]
ratio_components = AVERAGE(Components[ratio])
quantity_components = [quantity_ingredients] * [ratio_components]
quantity_components_i shoud get = ???
ingredient_namequantity_forecastratio_forecastquantity_ingredientsratio_componentsquantity_componentsquantity_components_i shoud get
Beef   0,99 35,07
Bun1270,5063,5   
Cheese5060,1996,1   
Dough5060,46232,8   
Flour   0,95 221,12
Lettuce2770,2876,2   
Meat1270,2126,7   
Oil5060,0735,40,301111,64
Onion1270,1012,7   
Salami5060,1155,7   
Salt   0,01 0,35
Sauce2770,0719,4   
Spices   0,20 3,79
Tomato sauce5060,1786,0   
Tomatoes1500,5075,00,947180,86

 

forecast:

product_nameproduct_idquantity
Salad100150
Pizza101506
Burger102127
Sandwich10312

ingredients:

product_nameproduct_idingredient_nameingredient_idratio
Salad100Lettuce10,45
Salad100Tomatoes20,5
Salad100Sauce30,05
Pizza101Dough110,46
Pizza101Tomato sauce120,17
Pizza101Oil2020,07
Pizza101Cheese130,19
Pizza101Salami140,11
Burger102Bun160,5
Burger102Lettuce180,1
Burger102Onion190,1
Burger102Sauce30,09
Burger102Meat220,21

components:

ingredient_nameingredient_idcomponent_namecomponent_idratio
Sauce3Spices2010,2
Sauce3Oil2020,8
Dough11Flour2030,95
Dough11Oil2020,05
Tomato sauce12Tomatoes20,94
Tomato sauce12Oil2020,06
Meat22Beef2060,99
Meat22Salt2090,01

ingredients_list:

ingredient_nameingredient_id
Spices201
Oil202
Flour203
Tomatoes2
Beef206
Salt209
Lettuce1
Sauce3
Dough11
Tomato sauce12
Cheese13
Salami14
Bun16
Lettuce18
Onion19
Meat22

 

Relations:

Ingredients_list[ingredient_id] 1:* Components[component_id]

Ingredients_list[ingredient_id] 1:* Ingredients[ingredient_id]

Ingredients[product_id] 1:* Forecast[product_id]

 

1 ACCEPTED SOLUTION
burakkaragoz
Community Champion
Community Champion

Hi @EvinMensler ,

This is a classic Bill of Materials (BOM) Explosion scenario. It is tricky because you are dealing with two layers of demand simultaneously:

  1. Direct Demand: When the product uses the item directly (e.g., Pizza uses Oil).

  2. Indirect (Derived) Demand: When the product uses an ingredient (like Dough), and that ingredient uses the item (Oil).

The problem with your current calculation is Context. When you select "Oil" in your visual, Power BI filters everything to "Oil". It cannot "see" the demand for "Dough" or "Sauce" unless we explicitly tell DAX to look for the Parent Items of the selected component.

Here is how you can calculate the Indirect Demand and add it to your total.

The Solution Measure

We need to iterate through the Components table to find all the "Parents" of the selected ingredient, calculate their demand, and then multiply by the component ratio.

Total Quantity Required = 
VAR DirectDemand = [quantity_ingredients]

VAR IndirectDemand = 
    SUMX(
        -- Iterate through the rows in the Components table (filtered by the selected Ingredient)
        'Components',
        
        VAR ComponentRatio = 'Components'[ratio]
        VAR ParentID = 'Components'[ingredient_id] -- The ID of the Parent (e.g., Dough)
        
        -- Calculate the demand for the Parent Ingredient
        VAR ParentDemand = 
            CALCULATE(
                [quantity_ingredients],
                -- Step 1: Remove the filter from the selected Child (Oil)
                ALL('Ingredients_list'),
                -- Step 2: Apply the filter for the Parent (Dough)
                'Ingredients_list'[ingredient_id] = ParentID
            )
            
        RETURN ParentDemand * ComponentRatio
    )

RETURN DirectDemand + IndirectDemand

How it works:

  1. DirectDemand: Keeps your existing logic for Level 1 usage.

  2. IndirectDemand: It looks at the Components table. If "Oil" is selected, it finds rows where Oil is a component (Parents: Dough, Sauce, etc.).

  3. CALCULATE: This is the magic part. It uses ALL to ignore that you selected "Oil", and then uses the ParentID to pretend we selected "Dough". It calculates how much Dough is needed using your existing measure.

  4. Result: It multiplies the Dough Demand * Oil Ratio and sums it up for all parents.

Important Note: This solution assumes a 2-Level Hierarchy (Product > Ingredient > Component). If you have deeper levels (e.g., Component > Sub-Component), you would need a more complex recursive pattern using PATH functions or Python/SQL prep. But for the structure you shared, this DAX pattern is the most efficient way.

Give this a try and let me know if the numbers match your expectations!


If my response resolved your query, kindly mark it as the Accepted Solution to assist others. Additionally, I would be grateful for a 'Kudos' if you found my response helpful.
This response was assisted by AI for translation and formatting purposes.

View solution in original post

4 REPLIES 4
burakkaragoz
Community Champion
Community Champion

Hi @EvinMensler ,

This is a classic Bill of Materials (BOM) Explosion scenario. It is tricky because you are dealing with two layers of demand simultaneously:

  1. Direct Demand: When the product uses the item directly (e.g., Pizza uses Oil).

  2. Indirect (Derived) Demand: When the product uses an ingredient (like Dough), and that ingredient uses the item (Oil).

The problem with your current calculation is Context. When you select "Oil" in your visual, Power BI filters everything to "Oil". It cannot "see" the demand for "Dough" or "Sauce" unless we explicitly tell DAX to look for the Parent Items of the selected component.

Here is how you can calculate the Indirect Demand and add it to your total.

The Solution Measure

We need to iterate through the Components table to find all the "Parents" of the selected ingredient, calculate their demand, and then multiply by the component ratio.

Total Quantity Required = 
VAR DirectDemand = [quantity_ingredients]

VAR IndirectDemand = 
    SUMX(
        -- Iterate through the rows in the Components table (filtered by the selected Ingredient)
        'Components',
        
        VAR ComponentRatio = 'Components'[ratio]
        VAR ParentID = 'Components'[ingredient_id] -- The ID of the Parent (e.g., Dough)
        
        -- Calculate the demand for the Parent Ingredient
        VAR ParentDemand = 
            CALCULATE(
                [quantity_ingredients],
                -- Step 1: Remove the filter from the selected Child (Oil)
                ALL('Ingredients_list'),
                -- Step 2: Apply the filter for the Parent (Dough)
                'Ingredients_list'[ingredient_id] = ParentID
            )
            
        RETURN ParentDemand * ComponentRatio
    )

RETURN DirectDemand + IndirectDemand

How it works:

  1. DirectDemand: Keeps your existing logic for Level 1 usage.

  2. IndirectDemand: It looks at the Components table. If "Oil" is selected, it finds rows where Oil is a component (Parents: Dough, Sauce, etc.).

  3. CALCULATE: This is the magic part. It uses ALL to ignore that you selected "Oil", and then uses the ParentID to pretend we selected "Dough". It calculates how much Dough is needed using your existing measure.

  4. Result: It multiplies the Dough Demand * Oil Ratio and sums it up for all parents.

Important Note: This solution assumes a 2-Level Hierarchy (Product > Ingredient > Component). If you have deeper levels (e.g., Component > Sub-Component), you would need a more complex recursive pattern using PATH functions or Python/SQL prep. But for the structure you shared, this DAX pattern is the most efficient way.

Give this a try and let me know if the numbers match your expectations!


If my response resolved your query, kindly mark it as the Accepted Solution to assist others. Additionally, I would be grateful for a 'Kudos' if you found my response helpful.
This response was assisted by AI for translation and formatting purposes.

You're a wizard! Thank you!

Haha, thank you @EvinMensler ! I appreciate the kind words.

DAX Context Transition can definitely feel like dark magic sometimes. But once you master how CALCULATE and ALL work together, you are the one controlling the wand.

Since the formula is working for you, could you please mark the previous reply as the Accepted Solution? It helps others find this BOM pattern quickly when they get stuck on the same issue.

Happy reporting!

On a followup check it seems the grand total is not the sum of all ingredients. How can i change it?

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

December 2025 Power BI Update Carousel

Power BI Monthly Update - December 2025

Check out the December 2025 Power BI Holiday Recap!

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.