列标题来自数据库时如何使用数据透视表

时间:2012-11-27 19:00:15

标签: sql sql-server sql-server-2008 sql-server-2008-r2 pivot

我从sql表中获取以下格式的数据:

DisplayName     PropertySystemName     PropertyDefaultName     PropertyValue
S1                  P1                    Property 1              Value 1
S1                  P2                    Property 2              Value 2
S1                  P3                    Property 3              Value 3
S1                  P4                    Property 4              Value 4
S1                  P5                    Property 5              Value 5
S1                  P6                    Property 6              Value 6
S1                  P7                    Property 7              Value 7
S1                  P8                    Property 8              Value 8
S1                  P9                    Property 9              Value 9
S1                  P10                   Property 10             Value 10

这是所需的输出:

DisplayName   Property 1   Property 2 Property 3
S1               Value 1     Value 2    Value 3

这是我的查询,但它不会产生所需的输出。

Select me.DisplayName,
     Min(Case PropertySystemName When 'P1' Then PropertyValue End) PropertyDefaultName,
     Min(Case PropertySystemName When 'P2' Then PropertyValue End) PropertyDefaultName,
     Min(Case PropertySystemName When 'P3' Then PropertyValue End) PropertyDefaultName
FROM vManagedEntity me

这是上述查询的输出:

DisplayName   PropertyDefaultName   PropertyDefaultName PropertyDefaultName
S1               Value 1                   Value 2           Value 3

如何修改查询以便生成所需的输出而无需对表头中已存在的列标题进行硬编码。

1 个答案:

答案 0 :(得分:2)

除非使用动态sql,否则不能将PropertyDefaultName列中的值用作列标题。使用动态SQL将允许您直接从表中提取列值和标题名称:

DECLARE @cols AS NVARCHAR(MAX),
    @colNames AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(PropertySystemName) 
                    from vManagedEntity
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colNames = STUFF((SELECT ',' + QUOTENAME(PropertySystemName) 
                          + ' as '+ replace(PropertyDefaultName, ' ', '')
                    from vManagedEntity
                    group by PropertySystemName, PropertyDefaultName
                    order by cast(replace(PropertySystemName, 'P', '') as int)
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT DisplayName, ' + @colNames + ' from 
             (
                select DisplayName, PropertySystemName,
                   PropertyValue
                from vManagedEntity
            ) x
            pivot 
            (
                min(PropertyValue)
                for PropertySystemName in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with demo

结果是:

| DISPLAYNAME | PROPERTY1 | PROPERTY2 | PROPERTY3 | PROPERTY4 | PROPERTY5 | PROPERTY6 | PROPERTY7 | PROPERTY8 | PROPERTY9 | PROPERTY10 |
----------------------------------------------------------------------------------------------------------------------------------------
|          S1 |   Value 1 |   Value 2 |   Value 3 |   Value 4 |   Value 5 |   Value 6 |   Value 7 |   Value 8 |   Value 9 |   Value 10 |