如何在SQL Server中旋转文本列?

27

我在我的数据库中有一个这样的表(SQL Server 2008)

ID      Type            Desc
--------------------------------
C-0 Assets          No damage
C-0 Environment     No impact
C-0 People          No injury or health effect
C-0 Reputation      No impact
C-1 Assets          Slight damage
C-1 Environment     Slight environmental damage
C-1 People          First Aid Case (FAC)
C-1 Reputation      Slight impact; Compaints from local community
我需要显示 资产、人员、环境和声誉 作为列,并显示匹配的描述作为值。但是当我运行数据透视查询时,所有值都为空。 请有人检查我的查询并告诉我哪里出错了?
Select severity_id,pt.[1] As People, [2] as Assets , [3] as Env, [4] as Rep
FROM 
(
    select * from COMM.Consequence
) As Temp
PIVOT
(
    max([DESCRIPTION]) 
    FOR [TYPE] In([1], [2], [3], [4])
) As pt

这是我的输出

ID  People  Assets   Env     Rep
-----------------------------------
C-0 NULL    NULL    NULL    NULL
C-1 NULL    NULL    NULL    NULL
C-2 NULL    NULL    NULL    NULL
C-3 NULL    NULL    NULL    NULL
C-4 NULL    NULL    NULL    NULL
C-5 NULL    NULL    NULL    NULL
2个回答

37
Select severity_id, pt.People, Assets, Environment, Reputation
FROM 
(
    select * from COMM.Consequence
) As Temp
PIVOT
(
    max([DESCRIPTION]) 
    FOR [TYPE] In([People], [Assets], [Environment], [Reputation])
) As pt

1
我很好奇为什么在第一个Select语句中使用了pt.People,但这里不需要pt前缀。 - Jowen
如果您不想在结果中显示severity_id怎么办? - Sr Jefers
@SrJefers 在派生表中使用查询,并在主查询中获取所需的列。 - Mikael Eriksson

0

我在SQL Server中重新创建了这个,它完美地工作。

我正在尝试将其转换为在不知道TYPE和DESCRIPTION列中的内容时也能正常工作。

我之前也使用过这个作为指南。(在SQL Server中使用“Pivot”将行转换为列)

编辑 ----

这是我针对上述问题的解决方案,在其中你不知道任何字段中的内容....

-- setup commands
        drop table #mytemp
        go

        create table #mytemp (
            id varchar(10),
            Metal_01 varchar(30),
            Metal_02 varchar(100)
        )


-- insert the data
        insert into #mytemp
        select 'C-0','Metal One','Metal_One' union all
        select 'C-0','Metal & Two','Metal_Two' union all
        select 'C-1','Metal One','Metal_One' union all
        select 'C-1','Metal (Four)','Metal_Four' union all
        select 'C-2','Metal (Four)','Metal_Four' union all
        select 'C-2','Metal / Six','Metal_Six' union all
        select 'C-3','Metal Seven','Metal_Seven' union all
        select 'C-3','Metal Eight','Metal_Eight' 

-- prepare the data for rotating:
        drop table #mytemp_ReadyForRotate
        select *,
                    replace(
                        replace(
                            replace(
                                replace(
                                    replace(
                                                mt.Metal_01,space(1),'_'
                                            ) 
                                        ,'(','_'
                                        )
                                    ,')','_'
                                    )
                                ,'/','_'
                                )
                            ,'&','_'
                            )
                    as Metal_No_Spaces
         into #mytemp_ReadyForRotate
         from #mytemp mt

    select 'This is the content of "#mytemp_ReadyForRotate"' as mynote, * from #mytemp_ReadyForRotate

-- this is for when you KNOW the content:
-- in this query I am able to put the content that has the punctuation in the cell under the appropriate column header

        Select id, pt.Metal_One, Metal_Two, Metal_Four, Metal_Six, Metal_Seven,Metal_Eight
        FROM 
        (
            select * from #mytemp
        ) As Temp
        PIVOT
        (
            max(Metal_01) 
            FOR Metal_02 In(
                                Metal_One,
                                Metal_Two,
                                Metal_Four,
                                Metal_Six,
                                Metal_Seven,
                                Metal_Eight
        )
        ) As pt


-- this is for when you DON'T KNOW the content:
-- in this query I am UNABLE to put the content that has the punctuation in the cell under the appropriate column header
-- unknown as to why it gives me so much grief - just can't get it to work like the above
-- it WORKS just fine but not with the punctuation field
        drop table ##csr_Metals_Rotated
        go

        DECLARE @cols AS NVARCHAR(MAX),
            @query  AS NVARCHAR(MAX),
            @InsertIntoTempTable as nvarchar(4000)

        select @cols = STUFF((SELECT ',' + QUOTENAME(Metal_No_Spaces) 
                            from #mytemp_ReadyForRotate
                            group by Metal_No_Spaces
                            order by Metal_No_Spaces
                    FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)') 
                ,1,1,'')

        set @query = 'SELECT id,' + @cols + ' into ##csr_Metals_Rotated from 
                     (
                        select id as id, Metal_No_Spaces 
                        from #mytemp_ReadyForRotate
                    ) x
                    pivot 
                    (
                        max(Metal_No_Spaces)
                        for Metal_No_Spaces in (' + @cols + ')
                    ) p '
        execute(@query);

        select * from ##csr_Metals_Rotated

虽然这理论上回答了问题,但最好在此处包含答案的基本部分,并提供参考链接。 - GhostCat
我必须道歉 - 我的“答案”并没有回答这个问题。-- 我只是需要在程序员不知道字段内容的情况下,sql server能够动态地创建字段并填充它们,所以我需要此帖子的发布答案是动态的。-- 我已经解决了这个问题,过几天我会在这里发布我的发现 - 现在时间很紧。 - user2792497

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接