来自一个数据透视表的SQL FOR XML多级别

时间:2014-04-23 16:36:47

标签: sql sql-server xml xpath for-xml

我一直试图使用FOR XML而没有成功执行以下操作。

来源表:

Country            | ID      | 1950        | 1955
-----------------------------------------------------
Country 1          | 1       | 2.43        | 2.55
Country 2          | 2       | 4.54        | 42.15

期望的输出:

<locations>
  <location>
    <loc name='Country 1' id='1' />
    <dub>
      <data year='1950' value='2.43' />
      <data year='1955' value='2.55' />
    </dub>
  </location>
  <location>
    <loc name='Country 2' id='2' />
    <dub>
      <data year='1950' value='4.54' />
      <data year='1955' value='42.15' />
    </dub>
  </location>
</locations>

是否有必要对dub元素进行解包?我希望最简单的SQL查询成为可能。 我认为FOR XML太难用了。您应该能够仅使用列名称上的简单XPath指定层次结构,但它不会接受,例如,[dub/data/@year=1955/@value]作为列[1950]的名称。

1 个答案:

答案 0 :(得分:2)

SQL Fiddle

MS SQL Server 2012架构设置

create table YourTable
(
  Country varchar(20),
  ID int,
  [1950] numeric(5,2),
  [1955] numeric(5,2)
)

insert into YourTable values
('Country 1',           1,        2.43,         2.55),
('Country 2',           2,        4.54,         42.15)

查询1

select T.Country as 'loc/@name',
       T.ID as 'loc/@id',
       (
         select 1950 as 'data/@year',
                T.[1950] as 'data/@value',
                null,
                1955 as 'data/@year',
                T.[1955] as 'data/@value'
         for xml path(''), type
       ) as dub
from YourTable as T
for xml path('location'), root('locations'), type

<强> Results

<locations>
  <location>
    <loc name="Country 1" id="1" />
    <dub>
      <data year="1950" value="2.43" />
      <data year="1955" value="2.55" />
    </dub>
  </location>
  <location>
    <loc name="Country 2" id="2" />
    <dub>
      <data year="1950" value="4.54" />
      <data year="1955" value="42.15" />
    </dub>
  </location>
</locations>