将行转换为sql server中的某些列

时间:2014-02-18 22:00:18

标签: sql-server pivot transpose unpivot

我有以下数据:

RecordYear TestA  TestB  TestC  TestD
2013        100   200    300    400
2014        150   250    350    450

我想要显示:

2013 TestType  Result  2014 Test Result
     TestA     100          TestA 150
     TestB     200          TestB 250
     TestC     300          TestC 350
     TestD     400          TestD 450

我已经使用了unpivot来获取部分路径,但我的查询最终得到:

2013
TestA  100
TestB  200
TestC  300
TestD  400

2014
TestA  150
TestB  250
TestC  350
TestD  450

我不知道如何移动2014年分组,以便它与2013年组相邻。任何帮助都会非常感激。

谢谢,

2 个答案:

答案 0 :(得分:0)

这将通过使用CTE执行枢轴然后在测试类型上自我加入来生成您想要的结果

WITH pv 
     AS (SELECT recordyear, 
                col, 
                val 
         FROM   table1 p 
                UNPIVOT (val 
                        FOR col IN (testa, 
                                    testb, 
                                    testc, 
                                    testd) ) AS unpvt) 
SELECT a.col [2013 TestType], 
       a.val [ Result ], 
       b.col [2014 TestType], 
       b.val [ Result] 
FROM   pv a 
       INNER JOIN pv b 
               ON a.col = b.col 
WHERE  a.recordyear = 2013 
       AND b.recordyear = 2014 

DEMO

然而它确实有局限性

  • 如果所采取的测试不同,您可能需要外部联接
  • 如果您想要超过一年,将无法正常工作
  • 列名称是硬编码以匹配where

答案 1 :(得分:0)

你可以通过取UNION来做到这一点,并为每年的加入结果集保留一个Id 1-4。简单

    ;WITH CTE1 AS
    (
        SELECT 1 ID, RecordYear,'TESTA' TESTTYPE,TESTA Result FROM #TABLE WHERE RecordYear=2013
        UNION ALL
        SELECT 2 ID,RecordYear,'TESTB' TESTTYPE,TESTB Result  FROM #TABLE WHERE RecordYear=2013
        UNION ALL
        SELECT 3 ID,RecordYear,'TESTC' TESTTYPE,TESTC Result  FROM #TABLE WHERE RecordYear=2013
        UNION ALL
        SELECT 4 ID,RecordYear,'TESTD' TESTTYPE,TESTD Result  FROM #TABLE WHERE RecordYear=2013
    )
    ,CTE2 AS
    (
        SELECT 1 ID,RecordYear,'TESTA' TEST,TESTA Result  FROM #TABLE WHERE RecordYear=2014
        UNION ALL
        SELECT 2 ID,RecordYear,'TESTB' TEST,TESTB Result  FROM #TABLE WHERE RecordYear=2014
        UNION ALL
        SELECT 3 ID,RecordYear,'TESTC' TEST,TESTC Result  FROM #TABLE WHERE RecordYear=2014
        UNION ALL
        SELECT 4 ID,RecordYear,'TESTD' TEST,TESTD Result  FROM #TABLE WHERE RecordYear=2014
    )
    SELECT NULL '2013' ,CTE1.TESTTYPE,CTE1.Result,NULL '2014',CTE2.TEST,CTE2.Result 
    FROM CTE1
    JOIN CTE2 ON CTE1.ID=CTE2.ID