SQL Server:将行转换为列

8

我有一张表,有两个列: sales(int)month(int)。我想要检索每个月对应的销售总额。输出需要以每个月为对应的12个列的形式呈现,其中每个列(month)只包含一个记录。

5个回答

10

你应该看一下PIVOT,以将行与列进行转换。这样可以避免为每个月编写一个select语句。示例代码如下:

DECLARE @salesTable TABLE
(
    [month] INT,
    sales INT
)

-- Note that I use SQL Server 2008 INSERT syntax here for inserting
-- multiple rows in one statement!
INSERT INTO @salesTable
VALUES (0, 2) ,(0, 2) ,(1, 2) ,(1, 2) ,(2, 2)
      ,(3, 2) ,(3, 2) ,(4, 2) ,(4, 2) ,(5, 2)
      ,(6, 2) ,(6, 2) ,(7, 2) ,(8, 2) ,(8, 2)
      ,(9, 2) ,(10, 2) ,(10, 2) ,(11, 2) ,(11, 2)

SELECT [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]
FROM
(
    SELECT [month], sales
    FROM @salesTable
) AS SourceTable
PIVOT
(
    SUM(sales)
    FOR [month] IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) AS PivotTable

你可能是对的,尽管问题没有提到 SQL Server 的版本。我更新了我的答案,以通知读者语法差异。 - Ronald Wildenberg

2

虽然不太美观,但这个方案非常有效

SELECT
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 1) [Sales1],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 2) [Sales2],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 3) [Sales3],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 4) [Sales4],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 5) [Sales5],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 6) [Sales6],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 7) [Sales7],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 8) [Sales8],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 9) [Sales9],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 10) [Sales10],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 11) [Sales11],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 12) [Sales12]

2
这里有一种替代方式来编写透视表,它可以给你更多的控制(特别是对于列名)。它也更容易生成动态SQL。
它类似于Robin的答案,但具有只对表进行一次访问的优点:
select
  Sales1 = sum( case when Month = 1 then Sales end )
, Sales2 = sum( case when Month = 2 then Sales end )
, Sales3 = sum( case when Month = 3 then Sales end )
-- etc..
from SalesTable;

我进行了一些调查,似乎新的枢轴运算符只是这种类型查询的语法糖。查询计划最终看起来完全相同。

有趣的是,反枢轴运算符似乎也只是语法糖。例如:

如果你有一个表格像这样:

Create Table Sales ( JanSales int, FebSales int, MarchSales int...)

您可以编写:

 select unpivoted.monthName, unpivoted.sales
 from Sales s
 outer apply (
    select 'Jan', JanSales union all
    select 'Feb', FebSales union all
    select 'March', MarchSales
 ) unpivoted( monthName, sales );

获取非透视化数据...

1

你可以使用OLAP来完成。这里是有关该主题的MSDN文档的另一个链接。

使用OLAP,您可以根据需要创建具有所需布局的信息立方体。

如果您不想采用这种方式,您将需要使用.NET、Java、TransacSQL或您喜欢的语言创建摘要表来操作SQLServer数据。


0

如果想要轻松地将列和其名称转置为行,您应该使用XML。在我的博客中,我已经用示例描述了这一点:链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接