Skip to main content
 首页 » 编程设计

sql之来自一个数据透视表的SQL FOR XML多层

2025年12月25日22kenshinobiy

我一直在尝试不成功地使用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]的名称。

请您参考如下方法:

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>