如何在T-SQL中透视XML列的属性

前端之家收集整理的这篇文章主要介绍了如何在T-SQL中透视XML列的属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要在表中的XML列上执行一个数据透视表,其中XML包含多个具有许多属性的元素.每个元素中的属性始终相同,但元素的数量会有所不同.让我举个例子…
FormEntryId |               FormXML                                    | DateCreated
====================================================================================
1           |<Root>                                                    | 10/15/2009
            |  <Form>                                                  |
            |    <FormData FieldName="Username" FieldValue="stevem" /> |
            |    <FormData FieldName="FirstName" FieldValue="Steve" /> |
            |    <FormData FieldName="LastName" FieldValue="Mesa" />   |
            |  </Form>                                                 |
            |</Root>                                                   |
            |                                                          |
------------------------------------------------------------------------------------
2           |<Root>                                                    | 10/16/2009
            |  <Form>                                                  |
            |    <FormData FieldName="Username" FieldValue="bobs" />   |
            |    <FormData FieldName="FirstName" FieldValue="Bob" />   |
            |    <FormData FieldName="LastName" FieldValue="Suggs" />  |
            |    <FormData FieldName="NewField" FieldValue="test" />   |
            |  </Form>                                                 |
            |</Root>                                                   |

我需要结束每个不同的FieldName属性值(在本例中为Username,FirstName,LastName和NewField)的结果集及其对应的FieldValue属性作为值.我上面给出的例子的结果如下:

FormEntryId | Username | FirstName | LastName | NewField | DateCreated
======================================================================
1           | stevem   | Steve     | Mesa     | NULL     | 10/15/2009
----------------------------------------------------------------------
2           | bobs     | Bob       | Suggs    | test     | 10/16/2009

我已经找到了使用静态列完成此操作的方法

SELECT
    FormEntryId,FormXML.value('/Root[1]/Form[1]/FormData[@FieldName="Username"][1]/@FieldValue','varchar(max)') AS Username,FormXML.value('/Root[1]/Form[1]/FormData[@FieldName="FirstName"][1]/@FieldValue','varchar(max)') AS FirstName,FormXML.value('/Root[1]/Form[1]/FormData[@FieldName="LastName"][1]/@FieldValue','varchar(max)') AS LastName,FormXML.value('/Root[1]/Form[1]/FormData[@FieldName="NewField"][1]/@FieldValue','varchar(max)') AS NewField,DateCreated
FROM FormEntry

但是,我想看看是否有一种方法可以根据不同的“FieldName”属性值集使列成为动态.

解决方法

看看 this dynamic pivot以及最近的 this one – 您基本上需要能够使用SELECT DISTINCT FieldName来动态构建查询.

以下是您的特定问题的完整答案(请注意,在知道列应显示的顺序时,从不同属性生成列表时存在列顺序弱点:

DECLARE @template AS varchar(MAX)
SET @template = 'SELECT 
    FormEntryId,{@col_list},DateCreated 
FROM FormEntry'

DECLARE @col_template AS varchar(MAX)
SET @col_template = 'FormXML.value(''/Root[1]/Form[1]/FormData[@FieldName="{FieldName}"][1]/@FieldValue'',''varchar(max)'') AS {FieldName}'

DECLARE @col_list AS varchar(MAX)

;WITH FieldNames AS (
    SELECT DISTINCT FieldName
    FROM FormEntry
    CROSS APPLY (
        SELECT X.FieldName.value('@FieldName','varchar(255)')
        FROM FormXML.nodes('/Root[1]/Form[1]/FormData') AS X(FieldName)
    ) AS Y (FieldName)
)
SELECT @col_list = COALESCE(@col_list + ',','') + REPLACE(@col_template,'{FieldName}',FieldName)
FROM FieldNames

DECLARE @sql AS varchar(MAX)
SET @sql = REPLACE(@template,'{@col_list}',@col_list)

EXEC (@sql)

猜你在找的MsSQL相关文章