【问题标题】:FOR XML in SQL Server: Elements based on common values of columnsSQL Server 中的 FOR XML:基于列公共值的元素
【发布时间】:2020-04-12 07:46:07
【问题描述】:

我正在使用 FOR XML 从 SQL 查询中创建一个 XML 文件。我希望元素基于特定列的常用值,在本例中为“位置”:

location    team    score
Adelong     SFP     104
Adelong     LIB     189
Adelong     CDP     9
Hurstville  SFP     14
Hurstville  LIB     64
Hurstville  CDP     13

我可以像这样轻松地将他逐行转换为 XML:

SELECT(SELECT location, team, score FROM MyTable FOR XML PATH('node'), TYPE ) FOR XML PATH(''), ROOT('root')

生成的 XML 看起来像这样:

  <node>
    <location>Adelong</location>
    <team>SFP</team>
    <score>104</score>
  </node>
  <node>
    <location>Adelong</location>
    <team>LIB</team>
    <score>189</score>
  </node>
  <node>
    <location>Adelong</location>
    <team>CDP</team>
    <score>9</score>
  </node>

但我真正想要的是:

<location name="Adelong">
    <node>
        <team>SFP</team>
        <score>104</score>
    </node>
    <node>
        <team>LIB</team>
        <score>189</score>
    </node>
    <node>
        <team>CDP</team>
        <score>9</score>
    </node>
</location>

【问题讨论】:

    标签: sql sql-server xml for-xml


    【解决方案1】:

    这是基于 XQuery FLWOR 表达式的解决方案。

    SQL

    -- DDL and sample data population, start
    DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [location] VARCHAR(20), team CHAR(3), score INT);
    INSERT INTO @tbl (location, team, score)
    VALUES
    ('Adelong'     ,'SFP',  104)
    ,('Adelong'    ,'LIB',  189)
    ,('Adelong'    ,'CDP',  9  )
    ,('Hurstville' ,'SFP',  14 )
    ,('Hurstville' ,'LIB',  64 )
    ,('Hurstville' ,'CDP',  13 );
    -- DDL and sample data population, end
    
    SELECT (
        SELECT *
        FROM @tbl
        FOR XML PATH('r'), TYPE, ROOT('root')).query('<root>
    {
       for $x in distinct-values(/root/r/location)
       return <location name="{$x}">
       {
            for $y in /root/r[location/text() = $x]
            return <node>
                {$y/team}
                {$y/score}
            </node> 
        }
        </location>
    }
    </root>');
    

    【讨论】:

      【解决方案2】:

      您可以使用获取不同位置的临时派生表,从中选择位置并在相关子查询中获取团队和分数。

      SELECT t1.location [@name],
             (SELECT t2.team,
                     t2.score
                     FROM mytable t2
                     WHERE t2.location = t1.location
                     FOR XML PATH('node'),
                             TYPE)
             FROM (SELECT DISTINCT
                          t1.location
                          FROM mytable t1) t1
             FOR XML PATH('location');
      

      db<>fiddle

      【讨论】:

      猜你喜欢
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      相关资源
      最近更新 更多