2015-09-21 42 views
5

这个问题是基于我Previous Question。 我需要扩展查询,以便我可以合并另外两个表(在另一个服务器实例上运行)。TSQL - 扩展查询由交叉的应用和数据透视

在这种Fiddle我加入这两个表:

CREATE TABLE LookUp 
([docID] varchar(10), [docType] varchar(100), [PartNumber] varchar(100), [internalID] varchar(100)); 
INSERT INTO LookUp 
([docID],[docType],[PartNumber], [internalID]) 
VALUES 
    ('D0305415', 'docTypeSub', 'X0455', null), 
    ('D0157632', 'docTypeMain', null, 'XY05570-XY05571'), 
    ('D0181511', 'docTypeMain',null, 'XY05572-XY05573'), 
    ('D0157633', 'docTypeMain', null, 'XY06380-XY06381'), 
    ('D0156037', 'docTypeSub', 'X0326', null), 
    ('D0151874', 'docTypeMain', null, 'XY05345'); 

CREATE TABLE Links 
    ([docIDTop] varchar(10), [docIDBottom] varchar(10)); 
INSERT INTO Links 
    ([docIDTop],[docIDBottom]) 
VALUES 
    ('D0157632', 'D0305415'), 
    ('D0181511', 'D0305415'), 
    ('D0157633', 'D0305415'), 
    ('D0151874', 'D0156037'); 

关于输出我需要在基于所述部分号码逗号分隔的柱以显示新internalID柱。

这是输出正确的数据查询:

select c.docType AS c_docTypeSub, c.docID AS C_docID, c.PartNumber AS C_PartNumber , 
b.docIDTop AS B_docIdTop, b.docIDBottom AS B_docIdBottom, a.* 
FROM LookUp a, Links b, LookUp c 
WHERE a.docType = 'docTypeMain' 
and a.docID = b.docIDTop and b.docIDBottom = c.docID 
and c.docType = 'docTypeSub' 
; 

我的问题是把那些拼在一起,这样我可以得到InternalID在我下面旧的查询显示:

---------------- 
-- OLD Query -- 
---------------- 
WITH CTE_no_nums 
AS 
(
SELECT docID, 
     CASE 
      WHEN PATINDEX('%[0-9]%',column1) > 0 
       THEN SUBSTRING(column1,0,PATINDEX('%[0-9]%',column1)) 
      ELSE column1 
     END AS cols, 
     COALESCE(column2,column3) AS vals 
FROM miscValues 
WHERE  column2 IS NOT NULL 
     OR column3 IS NOT NULL 
), 
CTE_Pivot 
    AS 
    (
    SELECT docID,partNumber,prio,[length],material 
    FROM CTE_no_nums 
    PIVOT 
    (
     MAX(vals) FOR cols IN (partNumber,prio,[length],material) 
    ) pvt 
) 

SELECT A.docId + ' # ' + B.vals AS [DocID # Plant], 
     A.docID, 
     A.partNumber, 
     A.prio, 
     B.vals AS Plant, 
     A.partNumber + '#' + A.material + '#' + A.[length] AS Identification, 
     A.[length], 
     SUBSTRING(CA.colors,0,LEN(CA.colors)) colors --substring removes last comma 
FROM CTE_Pivot A 
INNER JOIN CTE_no_nums B 
    ON  A.docID = B.docID 
     AND B.cols = 'Plant' 
CROSS APPLY ( SELECT vals + ',' 
       FROM CTE_no_nums C 
       WHERE cols = 'Color' 
        AND C.docID = A.docID 
       FOR XML PATH('') 
      ) CA(colors) 
      ; 

希望你能告诉我这是如何实现的。如果有不清楚的地方,请随时提问。不,我不负责数据结构的:-)

谢谢。

+0

你两个小提琴数据集似乎没有共同之处。实际上,如果您能够从MiscValues表中的PartNumber查找LookUp表中的PartNumber,我认为您的问题可以解决。重做数据,你应该能够从那里得出结论。同样,如果LookUp或Links中的docID字段与Document或MiscValues中的docID匹配,您的问题就解决了。如果情况并非如此,则您没有关系数据,这是不可能的。 –

+0

嗨,托尼,如果你投票赞成有效的答案并接受帮助你解决问题的答案,thx会很好! – Shnugo

回答

2

胡安·鲁伊斯卡斯蒂利亚延长我的答案给出,打开我的眼睛为您“链接” - 表。

这是我的最后一个建议,在一个更CTE解决您的问题:

CREATE TABLE MiscValues 
    ([docID] varchar(10) ,[rowNumber] int, [Column1] varchar(100), [Column2] varchar(100) 
    , [Column3] varchar(100)) 
; 
INSERT INTO MiscValues 
    ([docID],[rowNumber],[Column1], [Column2], [Column3]) 
VALUES 
    ('D0001',1, 'PartNumber', 'X0455', NULL), 
    ('D0001',2, 'Prio', '1', NULL), 
    ('D0001',3, 'Plant1', NULL, NULL), 
    ('D0001',4, 'Plant2', 'PlantB', NULL), 
    ('D0001',5, 'Plant3', 'PlantC', NULL), 
    ('D0001',6, 'Plant4', NULL, NULL), 
    ('D0001',7, 'Color1', 'white', NULL), 
    ('D0001',8, 'Color2', 'black', NULL), 
    ('D0001',9, 'Color3', 'blue', NULL), 
    ('D0001',10, 'Material', 'MA123', NULL), 
    ('D0001',11, 'Length', NULL, '10.87'), 

    ('D0002',1, 'PartNumber', 'X0326', NULL), 
    ('D0002',2, 'Prio', '2', NULL), 
    ('D0002',3, 'Plant1', 'PlantA', NULL), 
    ('D0002',4, 'Plant2', NULL, NULL), 
    ('D0002',5, 'Plant3', 'PlantC', NULL), 
    ('D0002',6, 'Plant4', 'PlantD', NULL), 
    ('D0002',7, 'Color1', NULL, NULL), 
    ('D0002',8, 'Color2', 'black', NULL), 
    ('D0002',9, 'Color3', NULL, NULL), 
    ('D0002',10, 'Color4', 'yellow', NULL), 
    ('D0002',11, 'Material', 'MA456', NULL), 
    ('D0002',12, 'Length', NULL, '16.43') 
; 

CREATE TABLE LookUp([docID] varchar(10), [docType] varchar(100), [PartNumber] varchar(100), [internalID] varchar(100)); 
INSERT INTO LookUp([docID],[docType],[PartNumber], [internalID]) 
VALUES 
    ('D0305415', 'docTypeSub', 'X0455', null), 
    ('D0157632', 'docTypeMain', null, 'XY05570-XY05571'), 
    ('D0181511', 'docTypeMain',null, 'XY05572-XY05573'), 
    ('D0157633', 'docTypeMain', null, 'XY06380-XY06381'), 
    ('D0156037', 'docTypeSub', 'X0326', null), 
    ('D0151874', 'docTypeMain', null, 'XY05345'); 

CREATE TABLE Links ([docIDTop] varchar(10), [docIDBottom] varchar(10)); 
INSERT INTO Links ([docIDTop],[docIDBottom]) 
VALUES 
    ('D0157632', 'D0305415'), 
    ('D0181511', 'D0305415'), 
    ('D0157633', 'D0305415'), 
    ('D0151874', 'D0156037'); 

WITH CTE_no_nums 
AS 
(
SELECT docID, 
     CASE 
      WHEN PATINDEX('%[0-9]%',column1) > 0 
       THEN SUBSTRING(column1,0,PATINDEX('%[0-9]%',column1)) 
      ELSE column1 
     END AS cols, 
     COALESCE(column2,column3) AS vals 
FROM miscValues 
WHERE  column2 IS NOT NULL 
     OR column3 IS NOT NULL 
), 
CTE_Pivot 
    AS 
    (
    SELECT docID,partNumber,prio,[length],material 
    FROM CTE_no_nums 
    PIVOT 
    (
     MAX(vals) FOR cols IN (partNumber,prio,[length],material) 
    ) pvt 
), 
CTE_InternalIDs AS 
(
     SELECT * 
     ,STUFF 
     ( 
     (SELECT ', ' + internalID 
     FROM LookUp AS L2 
     INNER JOIN Links L ON L2.docID=L.docIDTop 
     WHERE L2.internalID IS NOT NULL 
      AND L.docIDBottom=L1.docID 
     FOR XML PATH('') 
    ),1,2,'') AS ConcatenatedInternalIDs 
FROM LookUp AS L1 
WHERE L1.internalID IS NULL 
) 
SELECT A.docId + ' # ' + B.vals AS [DocID # Plant], 
     A.docID, 
     A.partNumber, 
     A.prio, 
     B.vals AS Plant, 
     A.partNumber + '#' + A.material + '#' + A.[length] AS Identification, 
     A.[length], 
     SUBSTRING(CA.colors,0,LEN(CA.colors)) colors, --substring removes last comma 
     IIDs.ConcatenatedInternalIDs 
FROM CTE_Pivot A 
INNER JOIN CTE_no_nums B 
    ON  A.docID = B.docID 
     AND B.cols = 'Plant' 
INNER JOIN CTE_InternalIDs AS IIDs ON A.partNumber = IIDs.PartNumber 
CROSS APPLY ( SELECT vals + ',' 
       FROM CTE_no_nums C 
       WHERE cols = 'Color' 
        AND C.docID = A.docID 
       FOR XML PATH('') 
      ) CA(colors) 
      ; 
--Clean up... 
/* 
DROP TABLE Links; 
DROP TABLE LookUp; 
DROP TABLE miscValues; 
*/ 

上述回来了这一点:

D0001 # PlantB D0001 X0455 1 PlantB X0455#MA123#10.87 10.87 white,black,blue XY05570-XY05571, XY05572-XY05573, XY06380-XY06381 
D0001 # PlantC D0001 X0455 1 PlantC X0455#MA123#10.87 10.87 white,black,blue XY05570-XY05571, XY05572-XY05573, XY06380-XY06381 
D0002 # PlantA D0002 X0326 2 PlantA X0326#MA456#16.43 16.43 black,yellow XY05345 
D0002 # PlantC D0002 X0326 2 PlantC X0326#MA456#16.43 16.43 black,yellow XY05345 
D0002 # PlantD D0002 X0326 2 PlantD X0326#MA456#16.43 16.43 black,yellow XY05345 

编辑:从这里开始,你会发现我的第一次回答(为了解胡安·鲁伊斯的回答):

我没有绝对的把握,如果我理解正确的,你...你想为一个连接列表添加到您的查询与所有internalID项网络使用LookUp的PartNumber。

你有问题:没有隐含的排序顺序...

你的

VALUES 
    ('D0305415', 'docTypeSub', 'X0455', null), 
    ('D0157632', 'docTypeMain', null, 'XY05570-XY05571'), 
    ('D0181511', 'docTypeMain',null, 'XY05572-XY05573'), 
    ('D0157633', 'docTypeMain', null, 'XY06380-XY06381'), 
    ('D0156037', 'docTypeSub', 'X0326', null), 
    ('D0151874', 'docTypeMain', null, 'XY05345'); 

插入似乎 “绑定” 值 “XY05570-XY05571”, “XY05572-XY05573”和“XY06380-XY06381”分配给零件编号“X0455”,值“XY05345”分配给零件编号“X0326”。但这是错误的!

您可以像下面这样做

VALUES 
    ('D0305415', 'docTypeSub', 'X0455', null), 
    ('D0157632', 'docTypeMain', 'X0455', 'XY05570-XY05571'), 
    ('D0181511', 'docTypeMain','X0455', 'XY05572-XY05573'), 
    ('D0157633', 'docTypeMain', 'X0455', 'XY06380-XY06381'), 
    ('D0156037', 'docTypeSub', 'X0326', null), 
    ('D0151874', 'docTypeMain', 'X0326', 'XY05345'); 

或者你也可以添加IDENTITY列和摆弄那些internalID IS NULL之间的所有条目。

随着第(填写每一行的零件号列),你可以得到拼接列表如下:

select c.docType AS c_docTypeSub, c.docID AS C_docID, c.PartNumber AS C_PartNumber , 
b.docIDTop AS B_docIdTop, b.docIDBottom AS B_docIdBottom, a.*, 
STUFF((SELECT ', ' + x.internalID 
     FROM LookUp AS x 
     WHERE x.PartNumber=c.PartNumber 
     FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,2,'') AS ConcatInternalID 
FROM LookUp a, Links b, LookUp c 
WHERE a.docType = 'docTypeMain' 
and a.docID = b.docIDTop and b.docIDBottom = c.docID 
and c.docType = 'docTypeSub' 
; 

职高,你可以添加到您的“老查询”以及作者:

只需添加这最后的选择

[...CTEs before...] 
SELECT A.docId + ' # ' + B.vals AS [DocID # Plant], 
     A.docID, 
     A.partNumber, 
     A.prio, 
     B.vals AS Plant, 
     A.partNumber + '#' + A.material + '#' + A.[length] AS Identification, 
     A.[length], 
     SUBSTRING(CA.colors,0,LEN(CA.colors)) colors, --substring removes last comma 
     STUFF((SELECT ', ' + x.internalID 
     FROM LookUp AS x 
     WHERE x.PartNumber=A.PartNumber 
     FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,2,'') AS ConcatInternalID 
[...FROM...] 

希望我理解这一点很好,这可以帮助你......

2

基于@Shnugo答案试试这个 未未优化(还) 答案,我认为@Shnugo doesn't检查链接表,因为你并不需要改变你的数据信息:

[...CTEs before...] 
    SELECT A.docId + ' # ' + B.vals AS [DocID # Plant], 
    A.docID, 
    A.partNumber, 
    A.prio, 
    B.vals AS Plant, 
    A.partNumber + '#' + A.material + '#' + A.[length] AS Identification, 
    A.[length], 
    SUBSTRING(CA.colors,0,LEN(CA.colors)) colors, --substring removes last comma 
    STUFF((SELECT ', ' + X.internalID 
    FROM LOOKUP X 
    INNER JOIN LINKS Z 
    ON X.DOCID = Z.DOCIDTOP 
    INNER JOIN LOOKUP X2 
    ON X2.DOCID = Z.DOCIDBOTTOM 
    WHERE X2.PartNumber=A.PartNumber 
    FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,2,'') AS ConcatInternalID 
[...FROM...] 
+1

谢谢你为Links表打开我的眼睛......你是对的,在那里找到缺失的信息......改变了我的答案。一个从我这里为你高兴 – Shnugo