如何组合连接表中的多个记录

时间:2016-12-09 22:41:18

标签: sql sql-server

我对此SQL查询的态度超出了我的范围。

我有两个表A和B,基于序列号的共享数据。在表A中,存在唯一的Serial Nr字段,而在B中,与特定序列号相关的细节通过公共组ID在多个记录上垂直链接。序列号条目作为MyData字段中的那些记录之一出现。我想连接所有共享相同" Group ID"的记录。到A中的单个字段。例如:

表A

Serial Nr      Name        Part Nr
 2950          Prod1       1234
 2955          Prod2       2345

表B

Group ID       MyData       Comments
    1           2950        serial nr
    1           2016-10     build month   
    2           2955        serial nr
    2           2015-11     build month

我想要表AxB

Serial Nr      Name        Part Nr    Table B data
 2950          Prod1       1234        serial nr, 2950, build month, 2016-10
 2955          Prod2       2345        serial nr, 2955, build month, 2015-11

我实际上并不想要共享组ID,但需要它作为连接键。

我曾试图用STUFF这样做,但无济于事。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我假设您的“TableB”还有一个“SerialNr”字段(您只是没有建模);

也就是说,你的表B实际上是这样的:

Serial Nr   Group ID    MyData      Comments
   2950     1           2950        serial nr
   2950     1           2016-10     build month   
   2955     2           2955        serial nr
   2955     2           2015-11     build month

如果是这样,以下查询将每个SerialNumber将“Comments”和“MyData”列聚合为一行:

SELECT  serialno ,STUFF((SELECT ', ' + Comments + ' - ' + MyData [text()]
FROM TableB 
WHERE SerialNo = t.SerialNo
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') AggregatedData
FROM TableB t
GROUP BY serialno

然后,您可以将该查询加入到原始TableA中,以获取您发布的结果集,即:

select * 
from TableA
join (SELECT  serialno ,STUFF((SELECT ', ' + Comments + ' - ' + MyData [text()]
      FROM TableB 
      WHERE SerialNo = t.SerialNo
      FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') AggregatedData
    FROM TableB t
    GROUP BY serialno
    ) AggregatedTableB
on TableA.SerialNo = AggregatedTableB.SerialNo

更新:

好的 - 基于这样一个事实,即你的“TableB”没有自己的SerialNr行,而是将其隐藏在表数据中。你需要找到一种方法将行级数据提取到列中

这是一个可以执行此操作的查询:

select tableB.GroupId, MyData, Comments, SerialNo 
from tableB
join
    (select MyData as serialNo, groupId
     from tableb
     where Comments ='serial nr') TableBWithSerialNo on tableB.GroupId = TableBWithSerialNo.GroupId

现在你有了这个将Serial No添加为列的查询,你可以在上面的查询中使用它来代替使用TableB。这就是它的样子:

SELECT  SerialNo ,STUFF((SELECT ', ' + Comments + ' - ' + MyData [text()]
FROM 
(select tableB.GroupId, MyData, Comments, SerialNo 
 from tableB
 join
    (select MyData as serialNo, groupId
     from tableb
     where Comments ='serial nr') TableBWithSerialNo on tableB.GroupId = TableBWithSerialNo.GroupId
) t1

WHERE t1.SerialNo = t2.SerialNo
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') AggregatedData
FROM (select tableB.GroupId, MyData, Comments, SerialNo 
 from tableB
 join
    (select MyData as serialNo, groupId
     from tableb
     where Comments ='serial nr') TableBWithSerialNo on tableB.GroupId = TableBWithSerialNo.GroupId
) t2
GROUP BY SerialNo

当然 - 这是一个丑陋的查询 - 但这是你正在使用的一个丑陋的表; - )

如果有的话,我建议将第一个查询放到视图中,然后在第二个查询中使用该视图 - 这样你就不会重复这么多代码,即;

create view TableBView as
select tableB.GroupId, MyData, Comments, SerialNo 
from tableB
join
    (select MyData as serialNo, groupId
     from tableb
     where Comments ='serial nr') TableBWithSerialNo on tableB.GroupId = TableBWithSerialNo.GroupId

go

SELECT  SerialNo ,STUFF((SELECT ', ' + Comments + ' - ' + MyData [text()]
FROM 
TableBView t1
WHERE t1.SerialNo = t2.SerialNo
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') AggregatedData
FROM TableBView t2
GROUP BY SerialNo