2009-04-29 104 views
8

我有一个列表sales(int)month(int)。我想检索每个月对应的销售额总和。我需要以12列的形式输出每个月份的相应数据,其中每个列(月份)将包含一个包含销售额的单个记录。SQL服务器:将行转换为列

回答

10

你应该看看PIVOT与列切换行。这可以防止每个月的选择语句。类似这样的:

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 
+0

你应该显示2008年之前的常规INSERT语法 – 2009-04-29 15:50:17

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] 
1

你可以用OLAP做到这一点。 Here是有关该主题的MSDN文档的另一个链接。

使用OLAP,您可以使用所需信息创建一个包含所需布局的多维数据集。

如果您不想这样做,您将不得不使用.NET,Java,TransacSQL或您的首选语言创建汇总表来操作SQLServer数据。

2

下面是另一种编写数据透视表的方法,它可以提供更多的控制权(特别是在列名上)。为其生成动态SQL也更容易一些。

它类似罗宾的答案,但有只打一次表的优点是:

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; 

我做了一些调查,这似乎是新的主运营商只是为这种类型的查询语法糖。查询计划最终看起来完全相同。

作为一个有趣的旁白,unpivot运算符似乎也只是语法糖。例如:

如果你有一个表所示:

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); 

,并获得逆转置数据...

0

要轻松转成列排其名称应该使用XML。在我的博客中,我用例子描述了这个:Link