Recursive Query for Bill Of Materials
I cannot thank you enough for all your help, Gordon. You helped me with some of the fundamental flaws and I finished some tweaks and for the most part have what I need.... at least for now. This has been driving me nuts for quite some time. The code I settled on is below in case it could be of help to someone else down the road
With BMStudy as (
select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 1 as BOMLevel
from BM010115 bm
where bm.PPN_I like '0123105-HWT' and bm.BOMNAME_I like ''
UNION ALL
select ba.ppn_i, bb.cpn_i, bb.bomname_i, bb.quantity_i,
(BOMLevel + 1) as BOMLevel
from BMStudy ba join
BM010115 bb
on ba.cpn_i = bb.ppn_i
where bb.BOMNAME_I like ''
)
select top 1000 BMStudy.*, i.ITEMDESC from BMStudy, iv00101 i
where CPN_I = itemnmbr
order by BOMLEVEL, CPN_I ASC
OPTION (MAXRECURSION 0)
Thanks again!
Recursive CTE Bill of Materials
I may be missing something, but it appears your JOIN
criteria precludes recursion:
INNER JOIN BOMCost AS bc
ON bqd.TRX_ID = bc.Assembly
ASM0002909
doesn't equal ASM0002914
, so no results from the bottom portion.
Update:
WITH BOMCost (Assembly, Component, PriceFromPO, Qty, BOMLevel)
AS
(
-- Anchor member definition
SELECT asl.TRX_ID, asl.ITEMNMBR, asl.UNITCOST, asl.SERLTQTY,
0 AS BOMLevel
FROM DBO.BM10400 AS asl
WHERE asl.TRX_ID = 'ASM0002909'
UNION ALL
-- Recursive member definition
SELECT asl.TRX_ID, asl.ITEMNMBR, asl.UNITCOST, asl.SERLTQTY,
BOMLevel + 1
FROM DBO.BM10400 AS asl
INNER JOIN DBO.BM10200_AssemblyQtyDetail AS bqd
ON asl.TRX_ID = bqd.TRX_ID
INNER JOIN BOMCost AS bc
ON bqd.TRANNUM = bc.Assembly
)
-- Statement that executes the CTE
SELECT DISTINCT Assembly, Component, PriceFromPO, Qty, BOMLevel
FROM BOMCost
Demo: SQL Fiddle
How can i fetch recursive data from Bill of materials tables
Use a recursive CTE. For example:
WITH BomTree (ID, Level, [Item Code], [Item Description], Depth)
AS
(
-- Anchor member definition
SELECT m.*, 0 AS Depth
FROM dbo.Master AS m
WHERE m.[ID] = ?
UNION ALL
-- Recursive member definition
SELECT m.*, t.Depth + 1 AS Depth
FROM dbo.Master AS m
INNER JOIN dbo.BOM AS b
ON m.[ID] = b.[Child Item ID]
INNER JOIN BomTree AS t
ON b.[Parent Item ID] = t.ID
)
-- Statement that executes the CTE
SELECT * FROM BomTree;
Sage Manufacturing Line 50 Bill Of Materials, SQL Recursive Two Table Tree iteration
WITH BOM_CTE (HID, HRef, HDesc, SC, CDesc, CHID, CQ, SEQ)
AS
(
--Anchor Member Definition
SELECT H.ID as HID, H.BomReference as HRef, H.Description as HDesc, C.StockCode as SC,C.Description as CDesc,C.HeaderID as CHID,C.Quantity as CQ,1 as SEQ
--GNT\SAGEL50.[sagel50_35648] refers to a database on a linked server on my main SQL server
FROM [GNT\SAGEL50].[sagel50_35648].[dbo].BomHeaders H
JOIN [GNT\SAGEL50].[sagel50_35648].[dbo].BomComponents C
ON H.ID = C.HeaderID
WHERE H.BomReference like 'SA000009%'
UNION ALL
--Recursive Member Definition
SELECT H.ID , H.BomReference f, H.Description , C.StockCode ,C.Description ,C.HeaderID ,C.Quantity, BC.SEQ+1
FROM [GNT\SAGEL50].[sagel50_35648].[dbo].BomHeaders H
JOIN [GNT\SAGEL50].[sagel50_35648].[dbo].BomComponents C
ON H.ID = C.HeaderID
JOIN BOM_CTE BC
ON H.BomReference = BC.SC
)
Select * From BOM_CTE
This Works Now, after I removed the aliases, all I need to do now is pass the BOMReference I want to iterate through instead of the hardcoded 'SA000009'%
SELECT Query for a Bill of Materials
Thank you for those who suggested CTE's. That was exactly what I was looking for.
Here is the query I ended up with after some trial and error.
USE PartDatabase
GO
DECLARE @TheSinglePart CHAR(30) = '100001';
WITH BOM (PARPRT_02, COMPRT_02, QTYPER_02)
AS
(
-- Anchor member definition
SELECT e.PARPRT_02, e.COMPRT_02, e.QTYPER_02
FROM dbo.Product_Structure AS e
WHERE e.PARPRT_02 = @TheSinglePart
UNION ALL
-- Recursive member definition
SELECT e.PARPRT_02, e.COMPRT_02, e.QTYPER_02
FROM dbo.Product_Structure AS e
INNER JOIN BOM AS d
ON e.PARPRT_02 = d.COMPRT_02
)
SELECT *
FROM BOM;
Get recursive material costs (Bill of Materials)
I am not familiar in pseudo-code and I am not sure what programming language you are familiar with. Hence I try to answer it in code form.
Recursive method : CollectRawProduct(Product)
CollectRawProduct(Product product) {
if (product has subProducts) {
for ( subProduct : subProducts ) { // iterates the sub products
CollectRawProduct( subProduct ); // visit subproduct
}
} else {
rawProductList.add(product) // add to a raw product list
}
}
The raw product list will contain the raw product like e.g for your case 4 legs one plate.
SQL server Query for Bill of materials quantity
You can use a recursive Common Table Expression to walk the hierarchy of parts, passing the quantity of the parent and multiplying the children's quantities by it.
DECLARE @bom int = 301755
CREATE TABLE #t(
BOM int,
KitID varchar(20),
SubAssy varchar(20),
BOMLevel int,
StdQty float
)
INSERT #t(BOM, KitID, SubAssy, BOMLevel, StdQty) VALUES
(301755, '301755', '31161201', 0, 1),
(301755, '301755', '29975413', 0, 2),
(301755, '301755', '299756', 0, 2),
(301755, '301755', '305958', 0, 1),
(301755, '305958', '311620', 1, 4),
(301755, '305958', '311620', 1, .1),
(301755, '299756', 'RDBSSL012', 1, .1),
(301755, '299756', 'RDBSSL012', 1, 3.417),
(301755, '29975413', 'PLTSSL902', 1, 1),
(301755, '29975413', 'CAPSSL4SCH40', 1, 1),
(301755, '29975413', 'PIPSSL4SCH40', 1, 3.96),
(301755, '29975413', 'LABSTR', 1, .166),
(301755, '31161201', 'PIPSSL2SCH40', 1, 4)
;WITH cte AS (
SELECT KitID, SubAssy, StdQty FROM #t WHERE KitID = @bom
UNION ALL
SELECT #t.KitID, #t.SubAssy, cte.StdQty * #t.StdQty FROM #t
INNER JOIN cte ON cte.SubAssy = #t.KitID
)
SELECT * FROM cte ORDER BY KitID, SubAssy
Related Topics
Get Last Friday's Date Unless Today Is Friday Using T-Sql
How to Create Xml Schema from an Existing Database in SQL Server 2008
How to Group by and Return Sum Row in Postgres
Get the Id of Last Inserted Records
Using Variables for Asc and Desc in Order By
Using Reserved Word Field Name in Documentdb
How to Run Raw SQL with Kotlin's Exposed Library
Recursive Cte to Find Parent Records
How to Match Multiple Column in a Table with SQLite Fts3
Convert Rows to Columns Using 'Pivot' in Mssql When Columns Are String Data Type
Error (Ora-00923: from Keyword Not Found Where Expected)
How to Use a SQL Select Statement with Access Vba
How to Compare Two Columns in the Same Table