Multi-Level BOM Cost Rollup SQL Query Generator
This tool writes a recursive common table expression that walks a multi-level bill of material and totals the cost of the purchased leaf components. Replace the placeholder names with your ERP's tables and run it against a copy of the data.
Fill in
SQL Server and Oracle use WITH. PostgreSQL, MySQL 8 and SQLite use WITH RECURSIVE.
Generic name. Replace with your ERP BOM table.
Guards against circular BOMs.
Recursive BOM explosion and cost rollup
WITH RECURSIVE bom_tree (parent_item, component_item, ext_qty, lvl) AS (
SELECT b.parent_item, b.component_item,
b.qty_per * (1 + b.scrap_pct / 100.0), 1
FROM bom_line b
WHERE b.parent_item = 'ASSY-1000'
UNION ALL
SELECT b.parent_item, b.component_item,
t.ext_qty * b.qty_per * (1 + b.scrap_pct / 100.0),
t.lvl + 1
FROM bom_line b
JOIN bom_tree t ON b.parent_item = t.component_item
WHERE t.lvl < 15
)
SELECT t.component_item,
SUM(t.ext_qty) AS total_qty,
c.unit_cost AS unit_cost,
SUM(t.ext_qty) * c.unit_cost AS ext_cost
FROM bom_tree t
JOIN item_cost c ON c.item = t.component_item
WHERE NOT EXISTS (
SELECT 1 FROM bom_line x
WHERE x.parent_item = t.component_item
)
GROUP BY t.component_item, c.unit_cost
ORDER BY ext_cost DESC;Total rolled-up material cost
-- Wrap the query above as a subquery named leaf_costs, then: SELECT SUM(ext_cost) AS rolled_material_cost FROM leaf_costs;
Table and column names here are generic placeholders, not any ERP's actual schema. Map them to your system's BOM and item cost tables, add effectivity date and revision filters, and remember that SQL Server may need explicit CAST on the quantity column so the recursive types match.
Ask BOM cost questions in plain language
An optional look at a read-only assistant that shows the query it ran against your ERP.
Optional. The tool and every export work without this. No spam.
How to use the generator
Choose the CTE keyword for your database, then enter the names of your BOM table, the parent and component columns, the quantity and scrap columns, and the item cost table. Enter the top-level item you want to explode and a maximum level. The query appears on the right, ready to copy into your SQL client.
- Pick WITH or WITH RECURSIVE for your engine
- Map the column names to your ERP schema
- Set a level cap to stop circular BOMs
How the query works
The anchor part selects the direct components of the top item and applies the scrap allowance as quantity times one plus scrap percent. The recursive part joins each component to its own BOM lines and multiplies the extended quantity down the levels. The final SELECT keeps only items that have no BOM of their own, which are the purchased or raw leaf items, joins them to unit cost and totals quantity times cost.
Reading the result
The output lists each leaf component, the total quantity needed for one top-level unit, the unit cost and the extended cost, sorted from the largest cost down. This is a material-only rollup. Labor, machine and overhead cost come from routings and rate tables and need separate joins. Compare the total with your ERP's standard cost for the same item to find stale item costs.
Common mistakes
Real BOMs have effectivity dates, revisions, phantom items and alternates, and a naive join will mix them. Add filters for the effective date and status. Also watch for components that are both bought and made, since the leaf test above treats any item without BOM lines as purchased. Finally, scrap treatment differs between systems: some store yield, not scrap, so convert before using the formula.
Frequently Asked Questions
Why use a recursive CTE for a BOM?
A BOM has an unknown number of levels, so a fixed number of self-joins cannot cover every product. A recursive CTE walks the structure one level at a time until no more child lines exist, and handles any depth within the level cap.
How do I handle circular BOM references?
The level cap stops the recursion after a set number of levels, which prevents an endless loop. If the query reaches the cap, the data likely contains a loop, and you should find and fix the offending parent and component pair in your item master.
Does this include labor and overhead?
No. It rolls up purchased material only. Labor and overhead come from routing operations and rates. Join your routing and work center tables to add run time, setup time and burden to the same top-level item.
Which databases does it work on?
PostgreSQL, MySQL 8 and later, SQLite, SQL Server and Oracle all support recursive CTEs. The keyword differs, and data type handling in the recursive column differs, so test on a small BOM first.
If you want BOM and cost questions answered without writing recursive SQL, Netray can connect a read-only assistant to your ERP database on your own servers.
Related Tools
SAP MBEW Price Control ABAP SELECT Generator
Fill in plant, material range and a drift threshold to get an ABAP report listing standard and moving average prices from MBEW.
Costing & FinanceManufacturing Cost Accounting Formulas Reference
A searchable lookup of the cost accounting formulas used in manufacturing: cost flows, overhead absorption, variances, break-even and pricing maths.
Costing & FinanceBasis of Estimate Document Template
Fill in the fields to produce a structured basis of estimate document that explains how a price was built.
Costing & FinanceProduct Costing Accuracy Health Assessment
A ten-question self-check that scores how trustworthy your standard costs and job costs are and what to fix first.
More Developer Tools tools
See all- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
- SAP QM Inspection Lot ABAP SELECT Generator
- SAP Quality Notification Pareto SQL Query Generator
- SAP QM Usage Decision BAPI Skeleton
- ABAP Custom Exception Class Generator
- ABAP Unit Test Class Generator