我正在尝试连接三个表并将两个不同的列连接成多行

时间:2014-05-26 06:14:25

标签: sql-server for-xml-path

我正在尝试连接三个表并将两个不同的列连接成多行。当我运行具有多个文件名和多个电话号码的常规查询时,我有四列数据。我想摆脱查询产生的重复项。

我希望将id不重复,并将不同的文件名连接到另一列,以逗号分隔。同样的事情也应该是这样,所有的电话号码连接成一行,并带有相应的id并用逗号分隔。

我发现了一些使用xml路径的例子,但它们只有两个表和两列。

下面我有三个表,我到目前为止的查询,以及我希望的查询。有人知道在连接表时如何进行嵌套的xml路径吗?

表:IPMFILE
ID FILENAME
10000.000 10000_45109.doc
10001.000 10001_45115.docx
10002.000 10002_47752.doc
10002.000 10002_45119.doc
10003.000 10003_45123.doc
10004.000 10004_45128.docx
10004.000 10004_45183.docx

表:人员
ID CITY
10000.000 Elkins Park
10001.000 4504 St. James Drive Plano
10002.000柯林斯堡 10003.000 Bound Brook
10004.000道纳斯格罗夫

表:电话
身份证电话
10000.000 215-7177179
10001.000 972-6187143
10002.000 970-4439376
10003.000首页732-3693106
10004.000 C 630-4648539
10004.000 H 630-9681673

SELECT PERSONS.ID, impfile.FILENAME, phonenumbers.phone, PERSONS.CITY 
FROM IMPFILE, Persons, Phonenumbers WHERE impfile.ID=Persons.ID 
AND phonenumbers.id=persons.id AND PERSONS.ID 
BETWEEN 10000 AND 10004 order by person



查询结果
ID FILENAME电话城市
10000.000 10000_45109.doc 215-7177179埃尔金斯公园
10001.000 10001_45115.docx 972-6187143 4504 St. James Drive Plano
10002.000 10002_47752.doc,970-4439376柯林斯堡 10002.000 10002_45119.doc 970-4439376柯林斯堡 10003.000 10003_45123.doc Home 732-3693106 Bound Brook
10004.000 10004_45128.docx C 630-4648539 Downers Grove
10004.000 10004_45183.docx C 630-4648539 Downers Grove
10004.000 10004_45128.docx H 630-9681673道纳斯格罗夫 10004.000 10004_45183.docx H 630-9681673 Downers Grove

针对每个ID连接的文件名连接的所需查询和每个ID连接的电话号码以及删除的重复项
ID FILENAME电话 CITY
10000.000 10000_45109.doc 215-7177179 埃尔金斯公园
10001.000 10001_45115.docx 972-6187143 4504 St. James Drive Plano
10002.000 10002_47752.doc,10002_45119.doc 970-4439376柯林斯堡
10003.000 10003_45123.doc 主页732-3693106绑定布鲁克 10004.000 10004_45128.docx,10004_45183.docxC 630-4648539,H​​ 630-9681673 Downers Grove

我在另一篇文章中发现了这个:

SELECT * 
FROM   ThisTable 
   OUTER APPLY (SELECT (SELECT SomeField + ' ' AS [data()] 
                        FROM   SomeTable 
                        WHERE  SomeTable.ID = ThisTable.ID 
                        FOR XML PATH ('')) AS ConcatenatedSomeField) A 
   OUTER APPLY (SELECT (SELECT SomeField2 + ' ' AS [data()] 
                        FROM   SomeTable 
                        WHERE  SomeTable.ID = ThisTable.ID 
                        FOR XML PATH ('')) AS ConcatenatedSomeField2) B 
   OUTER APPLY (SELECT (SELECT SomeField3 + ' ' AS [data()] 
                        FROM   SomeTable 
                        WHERE  SomeTable.ID = ThisTable.ID 
                        FOR XML PATH ('')) AS ConcatenatedSomeField3) C 

1 个答案:

答案 0 :(得分:0)

这是答案。 您需要在此处添加WHERE子句。此外,我发现您提供的代码中存在一些不匹配:例如ORDER BY person - 提供的表中没有此类列。

SELECT p.ID
  , imp.FILENAME
  , pn.phone
  , p.CITY 
FROM (
      SELECT DISTINCT ID,
              STUFF(( SELECT ',' + IPM.FILENAME AS [text()]
                      FROM IPMFILE AS IPM
                      WHERE IPM.ID = I.ID
                      FOR XML PATH('') 
                        ), 1, 1, '' )
            AS [Filename]
      FROM IPMFILE AS I
      ) as imp 
INNER JOIN Persons as p
  ON imp.ID=p.ID 
INNER JOIN (
      SELECT DISTINCT ID,
              STUFF(( SELECT ',' + p2.phone AS [text()]
                      FROM Phonenumbers AS p2
                      WHERE p2.ID = p1.ID
                      FOR XML PATH('') 
                        ), 1, 1, '' )
            AS [phone]
      FROM Phonenumbers AS p1
      ) as pn
  ON pn.id=p.id
ORDER BY p.id

关于子选择的一点解释。通过这部分,我们通过ID将行收集到一行:

SELECT ',' + p2.phone AS [text()]
FROM Phonenumbers AS p2
WHERE p2.ID = p1.ID 
FOR XML PATH('')

之后我们使用函数STUFF从收集的行中删除最后一个逗号。

此外,您可以在http://sqlfiddle.com/#!6/c9fc6/17

找到示例