Here is the query I use. Your looks a bit off with the select statement up top
WITH PartsExplosion (ParentPartNum, ParentSN, ChildPart, ChildSN, lv, rowid, Name, SORT, customer, TopSN, TopPart)
AS (
-- Anchor
SELECT p.PartNum as ParentPartNum,
sn.SerialNumber as ParentSN,
p.PartNum as ChildPart ,
sn.SerialNumber as ChildSN,
0 as lv,
cast('' as nvarchar(MAX)) as rowid,
CAST(p.PartDescription as nvarchar(100)) as Name,
CAST('\' + sn.SerialNumber as nvarchar(254)) as Sort,
p.shortchar10,
sn.SerialNumber as TopSN,
p.PartNum as TopPart
from part p
inner join SerialNo sn on sn.PartNum = p.PartNum
--and p.ClassID in ('FGA', 'FGD')
-- Recursive Call
UNION ALL
SELECT
BOM.ParentPartNum,
BOM.ParentSerialNo,
BOM.ChildPartNum,
BOM.ChildSerialNo,
lv + 1,
cast('' as nvarchar(MAX)) As Rowid,
CAST(REPLICATE ('| ' , lv + 1) + BOM.PartDescription as nvarchar(100)),
CAST(cte.Sort + '\' + BOM.ChildSerialNo as nvarchar(254)),
cte.customer,
CTE.TopSN,
CTE.TopPart
FROM PartsExplosion CTE
JOIN (SELECT sm.ParentPartNum, sm.ParentSerialNo, sm.ChildPartNum, sm.ChildSerialNo, p.PartDescription
from Erp.SerialMatch sm
inner join SerialNo sn on sm.ChildPartNum = sn.PartNum and sm.ChildSerialNo = sn.SerialNumber
inner join part p on p.PartNum = sn.PartNum
where sm.ParentSerialNo <> sm.ChildSerialNo
) AS BOM
ON CTE.ChildPart = BOM.ParentPartNum and CTE.ChildSN = BOM.ParentSerialNo
)
select PE.customer, PE.TopSN, PE.TopPart, PE.ParentPartNum, PE.ParentSN, PE.ChildPart as CompPart, PE.ChildSN as ComponentSN, PE.lv, PE.[Name] as Description,
sn.SNFirstShippedDt_c, sn.SNFirstShippedtoCusDt_c, sn.ShortChar01, oh.ordernum,oh.PONum
FROM PartsExplosion AS PE
inner join SerialNo as sn on sn.SerialNumber = pe.TopSn and sn.PartNum = PE.TopPart
inner join Erp.JobProd jp on jp.JobNum = sn.shortchar01
inner join OrderHed oh on jp.OrderNum = oh.OrderNum
ORDER BY sort