如何使用T-SQL数据透视表反转行和列

时间:2010-03-23 19:57:16

标签: sql tsql

我有一个返回一行的查询。但是,我想反转行和列,意味着将行显示为列,将列显示为行。我认为最好的方法是使用数据透视表,我不是专家。

这是我的简单查询:

SELECT Period1, Period2, Period3
FROM GL.Actuals
WHERE Year = 2009 AND Account = '001-4000-50031'
  

结果(带标题):

     

Period1,Period2,Period3

     

612.58,681.36,676.42

我希望结果看起来像这样:

  

期望的结果:

     

期间,金额

     

Jan,612.58

     

2月,681.36

     

Mar,676.42

这是一个简单的例子,但我真正追求的是比这更复杂。我意识到我可以通过使用几个SELECT命令来产生这些结果。我只是希望有人可以通过数据透视表或如果还有更好的方法来阐明如何实现这一目标。

3 个答案:

答案 0 :(得分:2)

对于一组固定的字段,您可以使用UNION的select语句,每个语句都可以获取其中一个字段。标准SQL没有提供一种方法来转换可变数量的字段的结果,例如select * from table

如果MSSQL有一个有帮助的扩展(比如pivot),我不知道它。

答案 1 :(得分:1)

尝试这样的事情(在MSSQL2008上测试):

DECLARE @Data TABLE(Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2))
INSERT @Data
VALUES (612.58, 681.36, 676.42)

SELECT Period, Amount
FROM (SELECT Period1 AS Jan, Period2 AS Feb, Period3 AS Mar FROM @Data) AS D
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar)) AS U

<强>更新

基于杰夫的评论,这是怎么回事:

DECLARE @Actuals TABLE(Account INT, [Year] INT, Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2))
INSERT @Actuals VALUES (1, 2010, 612.58, 681.36, 676.42)
INSERT @Actuals VALUES (1, 2009, 512.58, 581.36, 576.42)

SELECT Account, Period, Amount
FROM
(
    SELECT a.Account, a.Period1 AS Jan, a.Period2 AS Feb, a.Period3 AS Mar, a1.Period1 AS Jan1, a1.Period2 AS Feb1, a1.Period3 AS Mar1
    FROM @Actuals AS a
    LEFT OUTER JOIN @Actuals AS a1 ON a.Account = a1.Account AND a1.[Year] = a.[Year] - 1
    WHERE a.[Year] = 2010
) AS d
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar, Jan1, Feb1, Mar1)) AS u

或者,使用明确的年份列:

DECLARE @Actuals TABLE(Account INT, [Year] INT, Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2))
INSERT @Actuals VALUES (1, 2010, 612.58, 681.36, 676.42)
INSERT @Actuals VALUES (1, 2009, 512.58, 581.36, 576.42)

SELECT Account, [Year], Period, Amount
FROM
(
    SELECT a.Account, a.[Year], a.Period1 AS Jan, a.Period2 AS Feb, a.Period3 AS Mar
    FROM @Actuals AS a WHERE a.[Year] IN (2009, 2010)
) AS d
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar)) AS u

答案 2 :(得分:1)

检查不需要的功能,它的开销非常惊人。只需在嵌套的选择查询之上添加一个选择查询,然后在此处取消选择:

SELECT id,
   unnest(array['a', 'b', 'c']) AS colname,
   unnest(array[a, b, c]) AS thing
FROM foo
ORDER BY id;