我需要从XML文档中选择数据。该文档的结构如下例所示:
<parameters>
<set>
<attribId>4711</attribId>
<attribId>4712</attribId>
<matnr>000000000001206433</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
<set>
<attribId>4750</attribId>
<matnr>000000000001007885</matnr>
<matnr>000000000001007886</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
</parameters>
结果集应如下所示
attribId matnr vkorg spras
4711 000000000001206433 2420 NL
4712 000000000001206433 2420 NL
4750 000000000001007885 2420 NL
4750 000000000001007886 2420 NL
正如您所看到的,节点attribId和matnr可能会多次出现。目前我尝试选择以下方式:
SELECT
c.value('attribId[1]', 'int') AS attribId,
c.value('vkorg[1]', 'char(4)') AS VKORG,
c.value('spras[1]', 'char(2)') AS SPRAS,
c.value('matnr[1]', 'nvarchar(18)') AS MATNR
FROM @parameters.nodes('/parameters/set') AS t(c);
在这个select语句中,变量@parameters包含XML文档。结果显然是:
attribId matnr vkorg spras
4711 000000000001206433 2420 NL
4750 000000000001007885 2420 NL
缺少其他结果行。我如何选择获得第一个描述的结果集?提前谢谢。
答案 0 :(得分:1)
你可以试试这个:
首先将所有元素选择到单独的表中(我只是使用内联表)然后根据set id将它们连接在一起。在这种情况下,我推断出一个set id,因为它没有在你的xml中指定。
我还假设每组中每列至少有一个值 - 因此我使用内连接
DECLARE @parameters xml = '<parameters>
<set>
<attribId>4711</attribId>
<attribId>4712</attribId>
<matnr>000000000001206433</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
<set>
<attribId>4750</attribId>
<matnr>000000000001007885</matnr>
<matnr>000000000001007886</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
</parameters>'
select
attribId,
matnr,
vkorg,
spras
FROM (
select
t.c.value('count(for $a in . return $a/../../*[. << $a])','int') as parentID,
c.value('.', 'int') AS attribId
FROM @parameters.nodes('/parameters/set/attribId') AS t(c)
) a
INNER JOIN (
select
t.c.value('count(for $a in . return $a/../../*[. << $a])','int') as parentID,
c.value('.', 'char(4)') AS vkorg
FROM @parameters.nodes('/parameters/set/vkorg') AS t(c)
) v ON a.parentID = v.parentID
INNER JOIN (
select
t.c.value('count(for $a in . return $a/../../*[. << $a])','int') as parentID,
c.value('.', 'char(2)') AS spras
FROM @parameters.nodes('/parameters/set/spras') AS t(c)
) s ON s.parentID = a.parentID
INNER JOIN (
select
t.c.value('count(for $a in . return $a/../../*[. << $a])','int') as parentID,
c.value('.', 'nvarchar(18)') AS matnr
FROM @parameters.nodes('/parameters/set/matnr') AS t(c)
) m ON m.parentID = a.parentID
如果集合中有id,则可以执行此操作:
DECLARE @parameters xml = '<parameters>
<set id="1">
<attribId>4711</attribId>
<attribId>4712</attribId>
<matnr>000000000001206433</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
<set id="2">
<attribId>4750</attribId>
<matnr>000000000001007885</matnr>
<matnr>000000000001007886</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
</parameters>'
select
attribId,
matnr,
vkorg,
spras
FROM (
select
c.value('./../@id','varchar(200)') as parentID,
c.value('.', 'int') AS attribId
FROM @parameters.nodes('/parameters/set/attribId') AS t(c)
) a
INNER JOIN (
select
c.value('./../@id','varchar(200)') as parentID,
c.value('.', 'char(4)') AS vkorg
FROM @parameters.nodes('/parameters/set/vkorg') AS t(c)
) v ON a.parentID = v.parentID
INNER JOIN (
select
c.value('./../@id','varchar(200)') as parentID,
c.value('.', 'char(2)') AS spras
FROM @parameters.nodes('/parameters/set/spras') AS t(c)
) s ON s.parentID = a.parentID
INNER JOIN (
select
c.value('./../@id','varchar(200)') as parentID,
c.value('.', 'nvarchar(18)') AS matnr
FROM @parameters.nodes('/parameters/set/matnr') AS t(c)
) m ON m.parentID = a.parentID
答案 1 :(得分:1)
这可以为您提供您正在寻找的内容:
DECLARE @xml XML = '<parameters>
<set>
<attribId>4711</attribId>
<attribId>4712</attribId>
<matnr>000000000001206433</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
<set>
<attribId>4750</attribId>
<matnr>000000000001007885</matnr>
<matnr>000000000001007886</matnr>
<vkorg>2420</vkorg>
<spras>NL</spras>
</set>
</parameters>'
SELECT
attribId_node.value('(./text())[1]', 'varchar(50)') AS attribId,
matnr_node.value('(./text())[1]', 'varchar(50)') AS matnr,
vkorg_node.value('(./text())[1]', 'varchar(50)') AS vkorg,
spras_node.value('(./text())[1]', 'varchar(50)') AS spras
FROM @xml.nodes('/parameters/set') AS s (set_node)
CROSS APPLY s.set_node.nodes('./attribId') AS a (attribId_node)
CROSS APPLY s.set_node.nodes('./matnr') AS b (matnr_node)
CROSS APPLY s.set_node.nodes('./vkorg') AS c (vkorg_node)
CROSS APPLY s.set_node.nodes('./spras') AS d (spras_node)