在 SQL 服务器中将多列旋转到一列
Pivot multiple columns over one column in SQL Server
我有一个名为 #rdata 的临时 table,如下所示:
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
我想改成这个table:
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)
它似乎不起作用,知道我错过了什么吗?
只需执行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;
请注意,当我基于月份列创建动态列时,我是按月份值本身排序的。如果你想 have/sort 按时间顺序排列月份,你需要以不同的格式(如 2018-01、2017-10)存储数据,以便按其他列(如主键或类似的东西)排序。
我有一个名为 #rdata 的临时 table,如下所示:
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
我想改成这个table:
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)
它似乎不起作用,知道我错过了什么吗?
只需执行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;
请注意,当我基于月份列创建动态列时,我是按月份值本身排序的。如果你想 have/sort 按时间顺序排列月份,你需要以不同的格式(如 2018-01、2017-10)存储数据,以便按其他列(如主键或类似的东西)排序。