What I'm trying to do simply is for an item from the BOM table (Bill of Materials) get it's related components/products from BOMVERSION and then for those related components/products get their related components and products etc. down to 7 levels. I then want to pivot the results so that the related items get put in columns 0, 1, 2, 3, 4, 5, 6, 7
Please see attached example data and code. I'm using dynamics AX 2012 R2 but this example could be applied to any system that uses materials/products. I cannot get my query to complete however (I know I don't have dataareaid and partition I've left out for simplicity). the relationship is an itemid from BOM table is related to itemid in BOMVERSION through BOMID.
UPDATE : I've simplified data etc. to make as simple/clear as possible, so materials wood, metal, glass can go into making various products and materials themselves, and can be combined to make products or materials. Therefore I want to start with a base component, then explode the relationships out by levels.
DDL + DML:
USE tempdb;
IF OBJECT_ID('tempdb..#BOM') IS NOT NULL
DROP TABLE #BOM;
CREATE TABLE #BOM
(
ITEMID NVARCHAR(10) ,
BOMID NVARCHAR(10) ,
MATERIALNAME NVARCHAR(10)
);
INSERT INTO #BOM
VALUES ( N'113621', -- ITEMID - nvarchar(10)
N'1', -- BOMID - nvarchar(10)
N'Wood' -- MATERIALNAME - nvarchar(10)
);
INSERT INTO #BOM
VALUES ( N'234517', -- ITEMID - nvarchar(10)
N'2', -- BOMID - nvarchar(10)
N'Metal' -- MATERIALNAME - nvarchar(10)
);
INSERT INTO #BOM
VALUES ( N'378654', -- ITEMID - nvarchar(10)
N'3', -- BOMID - nvarchar(10)
N'Glass' -- MATERIALNAME - nvarchar(10)
);
IF OBJECT_ID('tempdb..#BOMVERSION') IS NOT NULL
DROP TABLE #BOMVERSION;
CREATE TABLE #BOMVERSION
(
ITEMID NVARCHAR(10) ,
BOMID NVARCHAR(10) ,
NAME NVARCHAR(20)
);
INSERT INTO #BOMVERSION
VALUES ( N'113477', -- ITEMID - nvarchar(10)
N'1', -- BOMID - nvarchar(10)
N'Oak' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113608', -- ITEMID - nvarchar(10)
N'1', -- BOMID - nvarchar(10)
N'Pine' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113622', -- ITEMID - nvarchar(10)
N'1', -- BOMID - nvarchar(10)
N'Wood Table' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113683', -- ITEMID - nvarchar(10)
N'2', -- BOMID - nvarchar(10)
N'Aluminium' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113689', -- ITEMID - nvarchar(10)
N'2', -- BOMID - nvarchar(10)
N'Steel' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113693', -- ITEMID - nvarchar(10)
N'2', -- BOMID - nvarchar(10)
N'Metal table' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113694', -- ITEMID - nvarchar(10)
N'3', -- BOMID - nvarchar(10)
N'Glass' -- NAME - nvarchar(10)
);
INSERT INTO #BOMVERSION
VALUES ( N'113695', -- ITEMID - nvarchar(10)
N'3', -- BOMID - nvarchar(10)
N'Glass BookCase' -- NAME - nvarchar(10)
);
--Query
WITH BOM1
AS ( SELECT B.ITEMID AS BITEMID ,
BV.ITEMID AS BVITEMID ,
B.MATERIALNAME ,
B.BOMID
FROM #BOM AS B
JOIN #BOMVERSION AS BV ON BV.BOMID = B.BOMID
),
EXPLODE
AS ( SELECT B.BITEMID ,
B.MATERIALNAME ,
B.BVITEMID ,
B.BOMID ,
0 AS [Level]
FROM BOM1 AS B
UNION ALL
SELECT B.BITEMID ,
E.MATERIALNAME ,
E.BVITEMID ,
E.BOMID ,
[E].[Level] + 1
FROM EXPLODE AS E
JOIN BOM1 AS B ON B.BOMID = E.BOMID
WHERE E.Level <= 6 --narrowing levels
)
SELECT *
FROM EXPLODE PIVOT ( MAX(BVITEMID) FOR Level IN ( [0], [1], [2], [3],
[4], [5], [6], [7] ) ) AS PVTBOM;
Output to look like
Well this is just to eliminate errors and get results, but I don't know if the results are correct:
You had
maxrecursion = 7
- this is not the place to narrow the levels. Levels are narrowed inside recursive part inCTE
.I suspect your recursion is not well organized, so can you simplify your test data? Just leave several rows and show the expected output.
EDIT1:
EDIT2: