在 SQL 中操作 XML 个节点(合并节点)
Manipulating XML Nodes in SQL (Merging nodes)
在SQL服务器中,如何将一组节点合并为一个?以下面的 XML 为例。我怎样才能从下面的格式转到在单个 'Attributes' 节点下有多个 'Attribute' 节点?
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes> -- **how can i remove this**
<Attributes> -- **and this**
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
编辑:我有这个问题的第二部分
鉴于此输入:
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
如何合并属性以实现此输出,其中值也根据匹配的 ID 合并?
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
<Value>103</Value>
</Values>
</Attribute>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
这是 FLWOR-XQuery
的方法:
DECLARE @xml XML=
N'<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>';
--查询会根据你的需要重新创建XML:
SELECT @xml.query
(
N'
<Thing>
{Thing/Id}
<Attributes>
{
for $a in //Attributes/Attribute
return $a
}
</Attributes>
</Thing>
'
)
结果
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
更新你的后续问题
在这种情况下,我宁愿切碎并重新创建完整的 XML:
DECLARE @xml XML=
N'<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>';
WITH attribs AS
(
SELECT a.value('Id[1]','int') AS Id
,v.value('.','int') AS Value
FROM @xml.nodes('/Thing/Attributes/Attribute') AS A(a)
OUTER APPLY a.nodes('Values/Value') AS B(v)
)
,distinctAttribIDs AS
(
SELECT DISTINCT Id FROM attribs
)
SELECT @xml.value('(/Thing/Id)[1]','int') AS Id
,(
SELECT da.Id
,(
SELECT a.Value
FROM attribs AS a
WHERE a.Id=da.Id
FOR XML PATH(''), ROOT('Values'),TYPE
)
FROM distinctAttribIDs AS da
FOR XML PATH('Attribute'),ROOT('Attributes'),TYPE
)
FOR XML PATH('Thing')
在SQL服务器中,如何将一组节点合并为一个?以下面的 XML 为例。我怎样才能从下面的格式转到在单个 'Attributes' 节点下有多个 'Attribute' 节点?
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes> -- **how can i remove this**
<Attributes> -- **and this**
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
编辑:我有这个问题的第二部分 鉴于此输入:
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
如何合并属性以实现此输出,其中值也根据匹配的 ID 合并?
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
<Value>103</Value>
</Values>
</Attribute>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
这是 FLWOR-XQuery
的方法:
DECLARE @xml XML=
N'<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>';
--查询会根据你的需要重新创建XML:
SELECT @xml.query
(
N'
<Thing>
{Thing/Id}
<Attributes>
{
for $a in //Attributes/Attribute
return $a
}
</Attributes>
</Thing>
'
)
结果
<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
<Attribute>
<Id>4</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
</Thing>
更新你的后续问题
在这种情况下,我宁愿切碎并重新创建完整的 XML:
DECLARE @xml XML=
N'<Thing>
<Id>160</Id>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>94</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>2</Id>
<Values>
<Value>103</Value>
</Values>
</Attribute>
</Attributes>
<Attributes>
<Attribute>
<Id>4</Id>
<Values>
<Value>106</Value>
</Values>
</Attribute>
</Attributes>
</Thing>';
WITH attribs AS
(
SELECT a.value('Id[1]','int') AS Id
,v.value('.','int') AS Value
FROM @xml.nodes('/Thing/Attributes/Attribute') AS A(a)
OUTER APPLY a.nodes('Values/Value') AS B(v)
)
,distinctAttribIDs AS
(
SELECT DISTINCT Id FROM attribs
)
SELECT @xml.value('(/Thing/Id)[1]','int') AS Id
,(
SELECT da.Id
,(
SELECT a.Value
FROM attribs AS a
WHERE a.Id=da.Id
FOR XML PATH(''), ROOT('Values'),TYPE
)
FROM distinctAttribIDs AS da
FOR XML PATH('Attribute'),ROOT('Attributes'),TYPE
)
FOR XML PATH('Thing')