使用SQL将行转换为列

使用SQL将行转换为列,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我正在努力解决一个问题。我想把行改成列,但我不知道怎么做。Pivot是一个解决方案,但是没有按照我希望的方式获取列。这里有一个例子 上面的表格就是我想要使用的表格,并将其转换为类似于下面的表格 基本上,四分之一需要在几年内为相同的请求ID在同一行上分发。我曾经尝试过这个案例,但对于这样的事情来说,这似乎是一种过度的杀伤力 这是一个开始 谢谢 要获得完全弹性的解决方案,您应该搜索动态枢轴。如果您提前几年知道,您可以使用: ;WITH cte AS ( SELECT ReqId,quater1

我正在努力解决一个问题。我想把行改成列,但我不知道怎么做。Pivot是一个解决方案,但是没有按照我希望的方式获取列。这里有一个例子

上面的表格就是我想要使用的表格,并将其转换为类似于下面的表格

基本上,四分之一需要在几年内为相同的请求ID在同一行上分发。我曾经尝试过这个案例,但对于这样的事情来说,这似乎是一种过度的杀伤力

这是一个开始


谢谢

要获得完全弹性的解决方案,您应该搜索动态枢轴。如果您提前几年知道,您可以使用:

;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 Dynamic Pivot您无需提前几年了解:

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;
看看:


也许能给你一条路。

太棒了。看到你的第一个答案,我创造了类似的东西。我正要发布解决方案,但我看到了您的更新。太好了,谢谢。