SQL 服务器 - 将 XML 列转换为分隔字符串
SQL Server - convert XML Column to delimited string
大师们,
我在 SQL 2012
中有如下 XML 列值
'<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
</AAA>
<AAA>
<Name>Name_E</Name>
<Value>Val_E</Value>
</AAA>
:
:
<AAA>
<Name>Name_Z</Name>
<Value>Val_Z</Value>
</AAA>
</XMLDoc>'
我们需要将前 2 个节点存储在单独的列中,并将其余节点(长度可能为 0 到 n)作为分隔字符串存储在第三列中。
我已尝试 SQL 如下所示,需要帮助来填充第 3 列
SELECT Col1 = Col.value('(/AAA/Value)[1]', 'varchar(255)') ,
Col2 = Col.value('(/AAA/Value)[2]', 'varchar(255)')
FROM table
我们需要输出为
Col1 Col2 Col3
Val_A Val_B Val_c,Val_D,Val_E....Val_n
大师们,
我能够通过以下 SQL
解决这个问题
SELECT Col1 = Col.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)') ,
Col2 = Col.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)') ,
Col3 = STUFF( (SELECT ',' + x.value('(Value)[1]', 'varchar(50)') FROM Col.nodes('/XMLDoc/AAA[position()>2]') AS Node(x) FOR XML PATH('')), 1, 1, '')
FROM table
让我知道是否有更好的解决方案
以下 T-SQL 应该可以解决您在 SQL Server 2012 中的问题,使用带有 FOR XML PATH
的子查询
SELECT Col1 = Col.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)'),
Col2 = Col.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)'),
Col3 = (SELECT ', '+P.N.value('text()[1]', 'varchar(max)')
FROM [table].Col.nodes('/XMLDoc/AAA[position()>2]/Value') P(N)
FOR XML PATH(''), type).value('substring(text()[1], 3)', 'varchar(max)')
FROM [table]
你可以查看这个...我从@svain 那里获取了一些内容。
declare @xmlstr varchar(1000) = '<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
</AAA>
<AAA>
<Name>Name_E</Name>
<Value>Val_E</Value>
</AAA>
</XMLDoc>'
declare @xml xml = (select cast( @xmlstr as xml))
select
distinct
xmlnodes.idnode.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)') as bb,
xmlnodes.idnode.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)') as dd,
Col3 = (SELECT ', '+xmlnodes.idnode.value('text()[1]', 'varchar(max)')
FROM @xml.nodes('/XMLDoc/AAA[position()>2]/Value') as xmlnodes(idnode)
FOR XML PATH(''), type).value('substring(text()[1], 3)', 'varchar(max)')
from
@xml.nodes('/XMLDoc/AAA') as xmlnodes(idnode)
大师们, 我在 SQL 2012
中有如下 XML 列值'<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
</AAA>
<AAA>
<Name>Name_E</Name>
<Value>Val_E</Value>
</AAA>
:
:
<AAA>
<Name>Name_Z</Name>
<Value>Val_Z</Value>
</AAA>
</XMLDoc>'
我们需要将前 2 个节点存储在单独的列中,并将其余节点(长度可能为 0 到 n)作为分隔字符串存储在第三列中。
我已尝试 SQL 如下所示,需要帮助来填充第 3 列
SELECT Col1 = Col.value('(/AAA/Value)[1]', 'varchar(255)') ,
Col2 = Col.value('(/AAA/Value)[2]', 'varchar(255)')
FROM table
我们需要输出为
Col1 Col2 Col3
Val_A Val_B Val_c,Val_D,Val_E....Val_n
大师们, 我能够通过以下 SQL
解决这个问题SELECT Col1 = Col.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)') ,
Col2 = Col.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)') ,
Col3 = STUFF( (SELECT ',' + x.value('(Value)[1]', 'varchar(50)') FROM Col.nodes('/XMLDoc/AAA[position()>2]') AS Node(x) FOR XML PATH('')), 1, 1, '')
FROM table
让我知道是否有更好的解决方案
以下 T-SQL 应该可以解决您在 SQL Server 2012 中的问题,使用带有 FOR XML PATH
的子查询SELECT Col1 = Col.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)'),
Col2 = Col.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)'),
Col3 = (SELECT ', '+P.N.value('text()[1]', 'varchar(max)')
FROM [table].Col.nodes('/XMLDoc/AAA[position()>2]/Value') P(N)
FOR XML PATH(''), type).value('substring(text()[1], 3)', 'varchar(max)')
FROM [table]
你可以查看这个...我从@svain 那里获取了一些内容。
declare @xmlstr varchar(1000) = '<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
</AAA>
<AAA>
<Name>Name_E</Name>
<Value>Val_E</Value>
</AAA>
</XMLDoc>'
declare @xml xml = (select cast( @xmlstr as xml))
select
distinct
xmlnodes.idnode.value('(/XMLDoc/AAA/Value)[1]', 'varchar(255)') as bb,
xmlnodes.idnode.value('(/XMLDoc/AAA/Value)[2]', 'varchar(255)') as dd,
Col3 = (SELECT ', '+xmlnodes.idnode.value('text()[1]', 'varchar(max)')
FROM @xml.nodes('/XMLDoc/AAA[position()>2]/Value') as xmlnodes(idnode)
FOR XML PATH(''), type).value('substring(text()[1], 3)', 'varchar(max)')
from
@xml.nodes('/XMLDoc/AAA') as xmlnodes(idnode)