使用FOR XML进行行连接,但是有多列?

Cod*_*ior 7 t-sql sql-server-2008

我经常使用如下查询:

SELECT *
FROM   ThisTable
       OUTER APPLY (SELECT (SELECT SomeField + ' ' AS [data()]
                            FROM   SomeTable
                            WHERE  SomeTable.ID = ThisTable.ID
                            FOR XML PATH ('')) AS ConcatenatedSomeField) A 
Run Code Online (Sandbox Code Playgroud)

我经常希望从这个表中获得多个连接的连接字段,而不是只有一个.我可以逻辑地这样做:

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 
Run Code Online (Sandbox Code Playgroud)

但是当需要更新任何东西时,它看起来很糟糕且容易出错; SomeTable通常也是一个很长的连接表列表,因此它也可能会对性能产生影响而反复使用相同的表.

有一个更好的方法吗?

谢谢.

小智 10

你可以这样做.此查询不是立即将XML值发送到字符串,而是使用TYPE关键字返回xml类型对象,然后可以查询该对象.三个查询函数在xml对象中搜索Somefield元素的所有实例,并返回仅包含这些值的新xml对象.然后value函数去除值周围的xml标记并将它们传递给varchar(max)

SELECT  ThisTable.ID
       ,[A].query('/Somefield').value('/', 'varchar(max)') AS [SomeField_Combined]
       ,[A].query('/Somefield2').value('/', 'varchar(max)') AS [SomeField2_Combined]
       ,[A].query('/Somefield3').value('/', 'varchar(max)') AS [SomeField3_Combined]
FROM    ThisTable
        OUTER APPLY (
                     SELECT (
                             SELECT SomeField + ' ' AS [SomeField]
                                   ,SomeField2 + ' ' AS [SomeField2]
                                   ,SomeField3 + ' ' AS [SomeField3]
                             FROM   SomeTable
                             WHERE  SomeTable.ID = ThisTable.ID
                            FOR
                             XML PATH('')
                                ,TYPE
                            ) AS [A]
                    ) [A]
Run Code Online (Sandbox Code Playgroud)