在SQL Server的一列上旋转多列

时间:2018-12-07 05:21:07

标签: sql-server tsql pivot dynamic-sql unpivot

我有一个名为#rdata的临时表,如下所示:

Months      KPI_1       KP1_2        KPI_3   
-------------------------------------------
Jan-18       x            x            x 
Feb-18       x            x            x 
Mar-18       x            x            x 
Apr-18       x            x            x 
Aug-18       x            x            x 

我想将其更改为该表:

 KPIs      Jan-18     Feb-18      Mar-18 ....
 -------------------------------------------
 KPI_1       x            x            x 
 KPI_2       x            x            x 
 KPI_3       x            x            x 

我走了这么远:

 ----Creating a list of Months  

    SELECT @Columns =   COALESCE(@Columns + ', ','') + QUOTENAME(Months)
     FROM
    (SELECT DISTINCT Months
      FROM  #rdata ) AS B



  SET @SQL = 'SELECT  ' + @Columns + ' KPI_1, KPI_2,KPI_3 FROM #rdata
  ) as PivotData

  PIVOT
  (
    FOR Months IN (' + @Columns + ')
   ) AS PivotResult'
   EXEC(@SQL)

似乎不起作用,知道我缺少什么吗?

1 个答案:

答案 0 :(得分:2)

只需先执行UNPIVOT,然后执行PIVOT。这是完整的工作示例:

DROP TABLE IF EXISTS #rdata;

CREATE TABLE #rdata
(
    [Months] VARCHAR(12)
   ,[KPI_1] INT
   ,[KPI_2] INT
   ,[KPI_3] INT
);

INSERT INTO #rdata ([Months], [KPI_1], [KPI_2], [KPI_3])
VALUES ('Jan-18 ', 1, 2, 3)
      ,('Feb-18 ', 4, 5, 6)
      ,('Mar-18 ', 7, 8, 9)
      ,('Apr-18 ', 10, 11, 12)
      ,('Aug-18 ', 13, 14, 15)


DECLARE @DynammicTSQLStatement NVARCHAR(MAX)
       ,@DynamicPIVOTColumns NVARCHAR(MAX);


SET @DynamicPIVOTColumns = STUFF
                          (
                                (
                                SELECT ',[' + CAST([Months] AS VARCHAR(12)) + ']'
                                FROM #rdata
                                GROUP BY [Months]
                                ORDER BY [Months]
                                FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                          );

SET @DynammicTSQLStatement = N'
SELECT *
FROM #rdata
UNPIVOT
(
    [value] FOR [KPIs] IN ([KPI_1], [KPI_2], [KPI_3])
) UNPVT
PIVOT
(
    MAX([value]) FOR [Months] IN (' + @DynamicPIVOTColumns + ')
) PVT'


EXEC sp_executesql @DynammicTSQLStatement;

enter image description here

请注意,当我基于month列创建动态列时,我是按month值本身进行排序的。如果要按时间顺序对月份进行排序,则需要以其他格式(如2018-01、2017-10)存储数据,以便按其他列(如主键或类似的关键字)进行排序。