我有一个SQL表,其中包含项目编号和将其构建到的程序集,因此每个项目都有一行,并且对于一个项目来说,要包含多个行通常是多行的。同样,每个程序集也有一条线,它们与THEY进入的程序集配对,并一直持续到我们到达顶部程序集为止(在Assembly字段中为NULL)。该表(ttibom010124)中的数据如下所示:
Assembly (t_mitm) Item (t_sitm)
TOPASSY1 SUBASSY1
TOPASSY2 SUBASSY2
SUBASSY1 PART1
SUBASSY1 PART2
SUBASSY2 PART3
SUBASSY2 PART4
PART1 SUBPART1
PART2 SUBPART2
PART3 SUBPART3
PART4 SUBPART4
每个项目还具有一组合同约定的下溢特征,定义为单个字符串中逗号分隔的整数,该字符串位于不同的表中。该表(tqmptc018124)如下所示:
Item (t_item) Characteristics (t_cdf_qcod)
SUBPART4 01,02,03
SUBPART3 04,05,06
SUBPART2 07,08,09
SUBPART1 10,11,12
PART4 13,14,15
PART3 16,17,18
PART2 19,20,21
PART1 22,23,24
SUBASSY2 25,26,27
SUBASSY1 28,29,30
TOPASSY1 NULL
TOPASSY2 NULL
还有另一个表,其中包含有关每个物料的描述性信息(ttcibd001124),尤其是其中使用该物料的整个产品线。该表实际上很大,但是相关的列是:
Item (t_item) Product Line (t_cpln) Item Code (t_citg)
SUBPART4 B21500 RAW
SUBPART3 B21500 RAW
SUBPART2 B21500 RAW
SUBPART1 B21500 RAW
PART1 B21500 MFG
PART2 B21500 MFG
PART3 B21500 MFG
PART4 B21500 MFG
SUBASSY2 B21500 MFG
SUBASSY1 B21500 MFG
TOPASSY1 B21500 FNG
TOPASSY2 B21500 FNG
最后一个表(ttcmcs061101)是一个小表,用于存储产品线代码和人类可读的说明之间的关系。以下是一些示例行:
Product Line (t_cpln) Description (t_dsca)
B21500 Fiber Optics
B36710 Eurofighter
B65100 CT Scan
我需要创建一个报告,在该报告中,我们将输入那些特征整数之一,然后在该表的字符串中搜索包含该整数的项,然后在每个项旁边显示相关的顶部程序集。我现在正在SSMS中进行测试,因此当前已对输入进行硬编码,但是当我将代码移至Report Builder时将对其进行参数化。
到目前为止,我有一些工作代码块可以单独完成我想要的工作。我可以在单个项目中进行硬编码,为此我可以找到顶级组件。我还有一个小块,它将接受一个特征并输出应用了该特征的所有项目。但是,当我尝试使用“特征SELECT”语句作为查找“顶级程序集”的块中的子查询时,我得到了大量不具有我感兴趣的“特征”的项目和程序集,即使这是其中的一部分。输入。
-- This block is a recursive CTE that finds the top assemblies
-- by moving from line to line through the Bill of Materials table.
WITH CTE_TopAssy (
AssyItem
,SubItem)
AS (
SELECT
BOM.t_mitm
,BOM.t_sitm
FROM ttibom010124 AS BOM
WHERE BOM.t_sitm IN
-- This is a subquery that is supposed to output all the Items
-- that contain the Characteristic number from the WHERE line.
(
SELECT
ItemsQD.t_item AS SubqueryItem
FROM tqmptc018124 AS ItemsQD
WHERE ItemsQD.t_cdf_qcod LIKE '%03%'
) -- 03 is the Characteristic we're searching by
UNION ALL
SELECT
BOM.t_mitm
,BOM.t_sitm
FROM ttibom010124 AS BOM
INNER JOIN CTE_TopAssy
ON BOM.t_sitm = CTE_TopAssy.AssyItem
)
-- This is the main query that produces the actual output.
-- It contains references to other tables from which other data tied to the Item number are pulled.
SELECT DISTINCT
LTRIM(RTRIM(CTE_TopAssy.AssyItem)) AS [Top Assembly]
,ItemData.t_cpln AS [Product Line]
,PLDesc.t_dsca AS [PL Name]
,LTRIM(RTRIM(CTE_TopAssy.SubItem)) AS Item
FROM CTE_TopAssy
INNER JOIN ttcibd001124 AS ItemData
ON CTE_TopAssy.AssyItem = ItemData.t_item
INNER JOIN ttcmcs061101 AS PLDesc
ON ItemData.t_cpln = PLDesc.t_cpln
--FNG is for Finished Goods, and is the characteristic by which we identify Top Assemblies
WHERE ItemData.t_citg = 'FNG'
ORDER BY
[Product Line]
,[Top Assembly]
;
输出采用预期的格式,但是我将返回的结果限制为具有所需特征的那些项目的“顶级装配体”,而不是获得了不相关且没有该特征的所有项目和装配体。输出显示如下:
Top Assembly Product Line PL Name Item
TOPASSY2 B21500 Fiber Optics SUBASSY2
所有内容都在正确的位置且类型正确,但不会被我们选择的特征过滤掉。在此示例输出中,我们搜索了'%03%',我们具有正确的Top Assembly,但是Item不正确-它应该是SUBPART4。在我的生产环境中,我得到的特征具有错误的特征或什至没有分配特征的物体,并且它们一直跟随着不应该作为输出一部分的顶级装配。
“%03%”搜索的预期结果将是:
Top Assembly Product Line PL Name Item
TOPASSY2 B21500 Fiber Optics SUBPART4
“%20%”搜索的预期结果将是:
Top Assembly Product Line PL Name Item
TOPASSY1 B21500 Fiber Optics PART2
没有错误消息。
我确定问题出在输入行数组而不是输入单个值,但我不知道该怎么办。
我用以下新测试数据添加了一个SQL Fiddle:http://sqlfiddle.com/#!18/e77e5/5/0
答案 0 :(得分:0)
没有数据与示例数据和查询一起返回。 请更新您的问题。
这是我的查询:
IF OBJECT_ID('tempdb..#ttibom010124') IS NOT NULL
DROP TABLE #ttibom010124
IF OBJECT_ID('tempdb..#tqmptc018124') IS NOT NULL
DROP TABLE #tqmptc018124
IF OBJECT_ID('tempdb..#ttcibd001124') IS NOT NULL
DROP TABLE #ttcibd001124
IF OBJECT_ID('tempdb..#ttcmcs061101') IS NOT NULL
DROP TABLE #ttcmcs061101
IF OBJECT_ID('tempdb..#CTE_TopAssy') IS NOT NULL
DROP TABLE #CTE_TopAssy
SELECT '6525039002' AS t_mitm, '8D004C0N01' AS t_sitm INTO #ttibom010124 UNION
SELECT '731114300G' AS t_mitm, '7311143000' AS t_sitm UNION
SELECT '731114300G' AS t_mitm, '7311113000' AS t_sitm UNION
SELECT '731114300G' AS t_mitm, '7C09E00PG0' AS t_sitm UNION
SELECT NULL AS t_mitm, '731114300G' AS t_sitm UNION
SELECT '731114300G' AS t_mitm, '9L35WMP032' AS t_sitm UNION
SELECT '731114400G' AS t_mitm, '7311144000' AS t_sitm UNION
SELECT '731114400G' AS t_mitm, '7311113000' AS t_sitm UNION
SELECT '6525039000' AS t_mitm, '8D004C0N01' AS t_sitm UNION
SELECT '6525039001' AS t_mitm, '8D004C0N01' AS t_sitm UNION
SELECT '6525039003' AS t_mitm, '8D004C0N01' AS t_sitm UNION
SELECT '6525039004' AS t_mitm, '8D004C0N01' AS t_sitm
SELECT '8D004C0N01' AS t_item, '1,4,10,12,19,21,34,44B,49B,59' AS t_cdf_qcod INTO #tqmptc018124 UNION
SELECT '7311144000' AS t_item, '1,4,10,12,19A,21,34,44A,49B,59' AS t_cdf_qcod UNION
SELECT '7C09E00PG0' AS t_item, '1,4,10B,12,19,21,34,44A,49B,59,61' AS t_cdf_qcod UNION
SELECT '7311113000' AS t_item, '1,4,12,32,41,54A' AS t_cdf_qcod
SELECT '8D004C0N01' AS t_item, 'B21500' AS t_cpln, 'MFG' AS t_citg INTO #ttcibd001124 UNION
SELECT '7311144000' AS t_item, 'B21500' AS t_cpln, 'RAW' AS t_citg UNION
SELECT '7C09E00PG0' AS t_item, 'B36710' AS t_cpln, 'RAW' AS t_citg UNION
SELECT '7311113000' AS t_item, 'B65100' AS t_cpln, 'FNG' AS t_citg
SELECT 'B21500' AS t_cpln, 'Fiber Optics' AS t_dsca INTO #ttcmcs061101 UNION
SELECT 'B36710' AS t_cpln, 'Eurofighter' AS t_dsca UNION
SELECT 'B65100' AS t_cpln, 'CT Scan' AS t_dsca
;
-- This block is a recursive CTE that finds the top assemblies
-- by moving from line to line through the Bill of Materials table.
WITH CTE_TopAssy (
AssyItem
,SubItem)
AS (
SELECT
BOM.t_mitm
,BOM.t_sitm
FROM #ttibom010124 AS BOM
WHERE BOM.t_sitm IN
-- This is a subquery that is supposed to output all the ICNs
-- that contain the SQAP number from the WHERE line.
(
SELECT
ItemsQD.t_item AS SubqueryItem
FROM #tqmptc018124 AS ItemsQD
WHERE ItemsQD.t_cdf_qcod LIKE '%49B%'
) -- 49B is the Characteristic we're searching by
UNION ALL
SELECT
BOM.t_mitm
,BOM.t_sitm
FROM #ttibom010124 AS BOM
INNER JOIN CTE_TopAssy
ON BOM.t_sitm = CTE_TopAssy.AssyItem
)
SELECT
*
INTO #CTE_TopAssy
FROM CTE_TopAssy
--AssyItem SubItem
--6525039000 8D004C0N01
--6525039001 8D004C0N01
--6525039002 8D004C0N01
--6525039003 8D004C0N01
--6525039004 8D004C0N01
--731114300G 7C09E00PG0
--731114400G 7311144000
--NULL 731114300G
-- This is the main query that produces the actual output.
-- It contains references to other tables from which other data tied to the Item number are pulled.
SELECT DISTINCT
LTRIM(RTRIM(#CTE_TopAssy.AssyItem)) AS [Top Assembly]
,ItemData.t_cpln AS [Product Line]
,PLDesc.t_dsca AS [PL Name]
,LTRIM(RTRIM(#CTE_TopAssy.SubItem)) AS Item
FROM #CTE_TopAssy
INNER JOIN #ttcibd001124 AS ItemData
ON #CTE_TopAssy.AssyItem = ItemData.t_item
INNER JOIN #ttcmcs061101 AS PLDesc
ON ItemData.t_cpln = PLDesc.t_cpln
--FNG is for Finished Goods, and is the characteristic by which we identify Top Assemblies
--WHERE ItemData.t_citg = 'FNG'
ORDER BY
[Product Line]
,[Top Assembly]
;
**编辑开始**
如果我很好理解,您想保留原始的子项目及其顶级装配。 我会建议为此创建一个标量值函数。
CREATE FUNCTION dbo.Get_Top_Assembly (
@P_SubItem VARCHAR(255))
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @Result_AssyItem VARCHAR(255);
WITH CTE_TopAssy
AS (
SELECT
BOM.t_mitm AS AssyItem
,BOM.t_sitm AS SubItem
FROM ttibom010124 AS BOM
WHERE BOM.t_sitm = @P_SubItem
UNION ALL
SELECT
BOM.t_mitm
,BOM.t_sitm
FROM ttibom010124 AS BOM
INNER JOIN CTE_TopAssy
ON BOM.t_sitm = CTE_TopAssy.AssyItem
)
SELECT @Result_AssyItem = CTE_TopAssy.AssyItem
FROM CTE_TopAssy
-- Return the result of the function
RETURN @Result_AssyItem
END
GO;
WITH CTE_TopAssy
AS (
SELECT
dbo.Get_Top_Assembly(ItemsQD.t_item) AS AssyItem
,ItemsQD.t_item AS SubItem
FROM tqmptc018124 AS ItemsQD
WHERE ItemsQD.t_cdf_qcod LIKE '%03%'
OR ItemsQD.t_cdf_qcod LIKE '%20%'
)
-- This is the main query that produces the actual output.
-- It contains references to other tables from which other data tied to the Item number are pulled.
SELECT DISTINCT
LTRIM(RTRIM(CTE_TopAssy.AssyItem)) AS [Top Assembly]
,ItemData.t_cpln AS [Product Line]
,PLDesc.t_dsca AS [PL Name]
,LTRIM(RTRIM(CTE_TopAssy.SubItem)) AS Item
FROM CTE_TopAssy
INNER JOIN ttcibd001124 AS ItemData
ON CTE_TopAssy.AssyItem = ItemData.t_item
INNER JOIN ttcmcs061101 AS PLDesc
ON ItemData.t_cpln = PLDesc.t_cpln
--FNG is for Finished Goods, and is the characteristic by which we identify Top Assemblies
WHERE ItemData.t_citg = 'FNG'
ORDER BY
[Product Line]
,[Top Assembly]
结果:
Top Assembly Product Line PL Name Item
TOPASSY1 B21500 Fiber Optics PART2
TOPASSY2 B21500 Fiber Optics SUBPART4
** 2nd Edit END BEGIN **
这里是CTE版本,尚未针对性能进行完全优化,但应该易于理解。
WITH CTE_Items
AS (
SELECT
ItemsQD.t_item AS SubItem
FROM tqmptc018124 AS ItemsQD
WHERE ItemsQD.t_cdf_qcod LIKE '%03%'
OR ItemsQD.t_cdf_qcod LIKE '%20%'
),
CTE_Assy_Hier
AS (
SELECT
BOM.t_mitm AS AssyItem
,BOM.t_sitm AS SubItem
,i.SubItem AS Original_SubItem
,1 AS Lvl
FROM ttibom010124 AS BOM
INNER JOIN CTE_Items i
ON BOM.t_sitm = i.SubItem
UNION ALL
SELECT
BOM.t_mitm
,BOM.t_sitm
,CTE_Assy_Hier.Original_SubItem
,1 + Lvl AS Lvl
FROM ttibom010124 AS BOM
INNER JOIN CTE_Assy_Hier
ON BOM.t_sitm = CTE_Assy_Hier.AssyItem
),
CTE_MAX_LVL
AS (
SELECT
MAX(Lvl) AS maxLvl
,Original_SubItem
FROM CTE_Assy_Hier
GROUP BY
Original_SubItem
),
CTE_TopAssy
AS (
SELECT
t.AssyItem
,t.Original_SubItem AS SubItem
FROM CTE_Assy_Hier t
INNER JOIN CTE_MAX_LVL m
ON t.Original_SubItem = m.Original_SubItem
AND t.Lvl = m.maxLvl
)
-- This is the main query that produces the actual output.
-- It contains references to other tables from which other data tied to the Item number are pulled.
SELECT DISTINCT
LTRIM(RTRIM(CTE_TopAssy.AssyItem)) AS [Top Assembly]
,ItemData.t_cpln AS [Product Line]
,PLDesc.t_dsca AS [PL Name]
,LTRIM(RTRIM(CTE_TopAssy.SubItem)) AS Item
FROM CTE_TopAssy
INNER JOIN ttcibd001124 AS ItemData
ON CTE_TopAssy.AssyItem = ItemData.t_item
INNER JOIN ttcmcs061101 AS PLDesc
ON ItemData.t_cpln = PLDesc.t_cpln
--FNG is for Finished Goods, and is the characteristic by which we identify Top Assemblies
WHERE ItemData.t_citg = 'FNG'
ORDER BY
[Product Line]
,[Top Assembly]
;
**编辑END **