我正在尝试解决问题。我想将行更改为列,但我不确定如何执行此操作。 Pivot 是一个解决方案,但没有按照我想要的方式获取列。这是一个例子。
上面的表格是我想要使用的表格,并将其转换为类似于下面的表格
基本上,对于相同的请求 ID,季度需要按年份分布在同一行上。我曾尝试过CASE,但这对于这样的事情来说似乎有点过分了。
这是一个fiddle首先。
谢谢。
最佳答案
要获得完全弹性的解决方案,您应该搜索动态枢轴。如果您提前几年知道,您可以使用:
;WITH cte AS
(
SELECT ReqId,quater1,quater2,quater3,quater4
,[q1] = CONCAT('Q1_',[year])
,[q2] = CONCAT('Q2_',[year])
,[q3] = CONCAT('Q3_',[year])
,[q4] = CONCAT('Q4_',[year])
FROM #forecast
)
SELECT ReqId
,[Q1_2014] = MAX([Q1_2014])
,[Q2_2014] = MAX([Q2_2014])
,[Q3_2014] = MAX([Q3_2014])
,[Q4_2014] = MAX([Q4_2014])
,[Q1_2015] = MAX([Q1_2015])
,[Q2_2015] = MAX([Q2_2015])
,[Q3_2015] = MAX([Q3_2015])
,[Q4_2015] = MAX([Q4_2015])
,[Q1_2016] = MAX([Q1_2016])
,[Q2_2016] = MAX([Q2_2016])
,[Q3_2016] = MAX([Q3_2016])
,[Q4_2016] = MAX([Q4_2016])
,[Q1_2017] = MAX([Q1_2017])
,[Q2_2017] = MAX([Q2_2017])
,[Q3_2017] = MAX([Q3_2017])
,[Q4_2017] = MAX([Q4_2017])
FROM cte
PIVOT (MAX(quater1) FOR [q1] IN ([Q1_2014],[Q1_2015],[Q1_2016],[Q1_2017])) AS pvt1
PIVOT (MAX(quater2) FOR [q2] IN ([Q2_2014],[Q2_2015],[Q2_2016],[Q2_2017])) AS pvt2
PIVOT (MAX(quater3) FOR [q3] IN ([Q3_2014],[Q3_2015],[Q3_2016],[Q3_2017])) AS pvt3
PIVOT (MAX(quater4) FOR [q4] IN ([Q4_2014],[Q4_2015],[Q4_2016],[Q4_2017])) AS pvt4
GROUP BY ReqId
输出:
╔════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦══════════╦═════════╗
║ ReqId ║ Q1_2014 ║ Q2_2014 ║ Q3_2014 ║ Q4_2014 ║ Q1_2015 ║ Q2_2015 ║ Q3_2015 ║ Q4_2015 ║ Q1_2016 ║ Q2_2016 ║ Q3_2016 ║ Q4_2016 ║ Q1_2017 ║ Q2_2017 ║ Q3_2017 ║ Q4_2017 ║
╠════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬══════════╬═════════╣
║ 1 ║ 10 ║ 20 ║ 30 ║ 40 ║ 50 ║ 60 ║ 70 ║ 80 ║ 90 ║ 100 ║ 110 ║ 120 ║ (null) ║ (null) ║ (null) ║ (null) ║
║ 2 ║ 10 ║ 20 ║ 30 ║ 40 ║ 50 ║ 60 ║ 70 ║ 80 ║ 90 ║ 100 ║ 110 ║ 120 ║ 130 ║ 140 ║ 150 ║ 160 ║
╚════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩══════════╩═════════╝
附录 1
或者:
;WITH cte AS (
SELECT ReqId, [q] ='Q1_' + CAST([year] AS CHAR(4)), quater = quater1 FROM #forecast
UNION ALL SELECT ReqId, [q] ='Q2_' + CAST([year] AS CHAR(4)), quater2 FROM #forecast
UNION ALL SELECT ReqId, [q] ='Q3_' + CAST([year] AS CHAR(4)), quater3 FROM #forecast
UNION ALL SELECT ReqId, [q] ='Q4_' + CAST([year] AS CHAR(4)), quater4 FROM #forecast
)
SELECT *
FROM cte
PIVOT (MAX(quater) FOR q IN (Q1_2014,Q2_2014,Q3_2014,Q4_2014,
Q1_2015,Q2_2015,Q3_2015,Q4_2015,
Q1_2016,Q2_2016,Q3_2016,Q4_2016,
Q1_2017,Q2_2017,Q3_2017,Q4_2017)
) AS pvt;
附录 2
动态枢轴(您不需要提前几年知道):
DECLARE @sql NVARCHAR(MAX) = N'
WITH cte AS (
SELECT ReqId,[q] =''Q1_'' + CAST([year] AS CHAR(4)),quater = quater1 FROM #forecast
UNION ALL SELECT ReqId,[q] =''Q2_'' + CAST([year] AS CHAR(4)),quater2 FROM #forecast
UNION ALL SELECT ReqId,[q] =''Q3_'' + CAST([year] AS CHAR(4)),quater3 FROM #forecast
UNION ALL SELECT ReqId,[q] =''Q4_'' + CAST([year] AS CHAR(4)),quater4 FROM #forecast
)
SELECT *
FROM cte
PIVOT (MAX(quater) FOR q IN (<placeholder>)
) AS pvt;';
DECLARE @cols NVARCHAR(MAX) =
STUFF((SELECT ',' + QUOTENAME('Q1_' + CAST([year] AS CHAR(4))) +
',' + QUOTENAME('Q2_' + CAST([year] AS CHAR(4))) +
',' + QUOTENAME('Q3_' + CAST([year] AS CHAR(4))) +
',' + QUOTENAME('Q4_' + CAST([year] AS CHAR(4)))
FROM (SELECT DISTINCT [year] FROM #forecast) cte
ORDER BY [year]
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') , 1, 1, '');
SET @sql = REPLACE(@sql, '<placeholder>', @cols);
EXEC [dbo].[sp_executesql] @sql;
关于sql - 使用 SQL 将行转换为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35220846/