将xlm列展平为新列

时间:2018-10-16 08:56:52

标签: sql-server xml

我有一张这样的桌子:

---id----Id2-----ID3-----
   1      2      <Account ID="123" NR = "234" Type="type1" Ratio = "31">
                  <FIELD>
                     <Name> Peter </Name>
                     <LastName> Johnson </LastName>
                     <Address> Millington </Address>
                     <Nr> 30 </Nr>
                  </FIELD>
                  <FIELD>
                     <Name> Jessica</Name>
                     <LastName> Johnson </LastName>
                     <Address> Millington </Address>
                     <Nr> 30 </Nr>
                  </FIELD>
                 </ACCOUNT>

ID3在每个帐户中可以有多个“字段”(大小不固定)。我希望这些字段成为每个ID的列。像这样:

---id--------id2--------Name-----Lastname-----Address-----Nr-----
    1         2         Peter     Johnson     Millington   30
    1         2         Jessica   Johnson     Millington   30

1 个答案:

答案 0 :(得分:1)

您可以将nodescross apply结合使用以将xml细分为行级:

declare @tmp table (id int,Id2 int,ID3 xml)
declare @xml XML = '<Account ID="123" NR = "234" Type="type1" Ratio = "31"> <FIELD> <Name> Peter </Name> <LastName> Johnson </LastName> <Address> Millington </Address> <Nr> 30 </Nr> </FIELD> <FIELD> <Name> Jessica</Name> <LastName> Johnson </LastName> <Address> Millington </Address> <Nr> 30 </Nr> </FIELD> </Account>'

insert into @tmp values(1, 2, @xml)

SELECT x.id
      ,x.id2
      ,c.value('Name[1]'    , 'nvarchar(200)') AS [Name]
      ,c.value('LastName[1]', 'nvarchar(200)') AS LastName
      ,c.value('Address[1]' , 'nvarchar(200)') AS [Address]
      ,c.value('Nr[1]'      , 'nvarchar(200)') AS Nr
FROM @tmp x
cross apply x.ID3.nodes('Account/FIELD') T(c)

结果:

enter image description here

请注意,您有不匹配的标签(<Account></ACCOUNT><Name></NAME>)。标签的大小写在开始和结束标签中必须相等。

在您的特定情况下,查询应如下所示(只需将[YOUR_TABLE_NAME_HERE]替换为表的实际名称):

SELECT x.id
      ,x.id2
      ,c.value('Name[1]'    , 'nvarchar(200)') AS [Name]
      ,c.value('LastName[1]', 'nvarchar(200)') AS LastName
      ,c.value('Address[1]' , 'nvarchar(200)') AS [Address]
      ,c.value('Nr[1]'      , 'nvarchar(200)') AS Nr
FROM [YOUR_TABLE_NAME_HERE] x
cross apply x.ID3.nodes('Account/FIELD') T(c)