将多组键值行转换为 XML

Convert groups of multiple key-value rows to XML

我有一个名为 userInfo 的 table,其数据类似于以下内容:

Id, Field, Value
---------------------
1, FirstName, John
1, LastName, Smith
1, Age, 25
1, Gender, Male
2, FirstName, Jane
2, LastName, Smythe
2, Age, 24
2, Gender, Female

我需要的是一些 T-SQL,它将为具有以下结构的每个 ID 生成一行:

行:1

<FieldValues>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<Age>25</Age>
<Gender>Male</Gender>
</FieldValues>

行:2

<FieldValues>
<FirstName>Jane</FirstName>
<LastName>Smythe</LastName>
<Age>24</Age>
<Gender>Female</Gender>
</FieldValues>

我已经尝试了一些方法来得到这个,但无法弄清楚。

编辑: 我在此处提供的字段列表(即名字、姓氏等)不是静态字段列表。我将一直添加和删除此列表,以便查询能够自动处理)。理想情况下,我可以使用类似 FOR XML PATH('FieldValues')

这是一种方法:

SELECT '<FieldValues>'+
       '<FirstName>'+fn.Value +'</FirstName>' +
       '<LastName>'+ln.Value +'</LastName>' +
       '<Age>'+age.Value +'</Age>' +
       '<Gender>'+gender.Value +'</Gender>' +
       '</FieldValues>
FROM (SELECT DISTINCT ID FROM userInfo) t
JOIN userInfo fn ON t.ID = fn.ID and fn.Field = 'FirstName'
JOIN userInfo ln ON t.ID = ln.ID and ln.Field = 'LastName'
JOIN userInfo age ON t.ID = age.ID and age.Field = 'Age'
JOIN userInfo gender ON t.ID = gender.ID and gender.Field = 'Gender'

工作原理:

首先,我只创建 table 唯一 ID 号。

SELECT DISTINCT ID FROM table 

然后我使用这个 table 为每个字段连接回主 table。 (每个连接的每个 ID 都只有一行。)

JOIN table fn ON t.ID = fn.ID and fn.Field = 'FirstName'
JOIN table ln ON t.ID = ln.ID and ln.Field = 'LastName'
JOIN table age ON t.ID = age.ID and age.Field = 'Age'
JOIN table gender ON t.ID = gender.ID and gender.Field = 'Gender'

最后我创建了一个按您需要格式化的字符串。

'<FieldValues>'+
'<FirstName>'+fn.Value +'</FirstName>' +
'<LastName>'+ln.Value +'</LastName>' +
'<Age>'+age.Value +'</Age>' +
'<Gender>'+gender.Value +'</Gender>' +
'</FieldValues>

附加说明:建议不要在 xml 上使用驼峰式大小写,因为 xml 是区分大小写的,任何使用大小写都是一种痛苦 -- 大多数情况下只使用全部小写。

您可以使用 for xml path('') 将 XML 构建为字符串,然后转换为 XML。

select T.Id,
       cast('<FieldValues>' + (
                              select '<'+T2.Field+'>'+
                                       (select T2.Value as '*' for xml path(''))+
                                     '</'+T2.Field+'>'
                              from dbo.YourTable as T2
                              where T.Id = T2.Id
                              for xml path(''), type
                              ).value('text()[1]', 'varchar(max)') +
            '</FieldValues>' as xml)  as FieldValues
from dbo.YourTable as T
group by T.Id;

SQL Fiddle

这部分 (select T2.Value as '*' for xml path('')) 用于处理需要作为值中的实体的字符,例如 &