declare @x as xml ='<root>
<n1>hello world</n1>
<n2>A0001</n2>
<n2>A0002</n2>
<n2>A0003</n2>
<n2>A0004</n2>
</root>'
select xroot.value('(n1)[1]', 'varchar(255)') as n1,
xroot.query('n2/text()') as n2
from @x.nodes('/root') as xmlt1(xroot)
该查询的结果是
n1 | n2
hello world | A0001A0002A0003A0004
但是我想要下面的结果,我该怎么写t-sql
n1 | n2
hello world | A0001,A0002,A0003,A0004
最佳答案
你可以试试这个:
declare @x as xml ='<root>
<n1>hello world</n1>
<n2>A0001</n2>
<n2>A0002</n2>
<n2>A0003</n2>
<n2>A0004</n2>
</root>';
SELECT @x.value('(/root/n1/text())[1]','nvarchar(max)') AS n1
,@x.query('data(/root/n2)').value('.','nvarchar(max)');
可惜的是data()
不允许指定分隔符。它将永远是一片空白。但你可以使用REPLACE()
:
SELECT @x.value('(/root/n1/text())[1]','nvarchar(max)') AS n1
,REPLACE(@x.query('data(/root/n2)').value('.','nvarchar(max)'),' ',',');
回撤:如果您的值可能包含空白,则这将失败......
您可以使用 XQuery 来代替:
SELECT @x.value('(/root/n1/text())[1]','nvarchar(max)') AS n1
,STUFF(
@x.query('for $n2 in /root/n2/text()
return <x>{concat(",",$n2)}</x>').value('.','nvarchar(max)'),1,1,'');
在这种方法中,我们使用 FLWOR 查询来运行 <n2>
元素并创建一个新的 XML,其中内容用逗号扩展:
<x>,A0001</x>
<x>,A0002</x>
<x>,A0003</x>
<x>,A0004</x>
我们可以将其与 XQuery 路径 '.'
一起读取 。删除前导逗号使用 STUFF()
(就像类似的字符串聚合方法一样)。我们可以使用XQuery sub-string()
也是:
SELECT @x.value('(/root/n1/text())[1]','nvarchar(max)') AS n1
,@x.query('for $n2 in /root/n2/text()
return <x>{concat(",",$n2)}</x>')
.value('substring(.,2,1000)','nvarchar(max)')
关于xml - 如何在t-sql中连接peer节点的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62631825/