【问题标题】:Manipulating XML Nodes in SQL (Merging nodes)在 SQL 中操作 XML 节点(合并节点)
【发布时间】:2016-12-09 20:49:22
【问题描述】:

在 SQL Server 中,如何将一组节点合并为一个?以下面的 XML 为例。如何从下面的格式转到在单个“属性”节点下拥有多个“属性”节点?

<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>

【问题讨论】:

  • 这个 XML 是如何生成的?看起来,好像最好在生成它时解决它......这是在你的控制之下吗?
  • 是否总是有一个元素&lt;Id&gt;,其余的只是&lt;Attributes&gt;
  • 我同意,最好的办法是在生成期间修复它,但这不是一个选项。第二个问题的答案是肯定的。
  • 好的,第二个让我给出的答案看起来很好:-)
  • 谢谢!我不知道这是可能的。如果你有时间,我用一个后续问题编辑了原始帖子。再次感谢!

标签: sql-server xml sqlxml


【解决方案1】:

这是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')

【讨论】:

  • 令人印象深刻。我不知道 FLWOR。
猜你喜欢
  • 2015-08-04
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
相关资源
最近更新 更多