2009-04-29 85 views
8

Tôi có một bảng có các cột sales(int), month(int). Tôi muốn lấy tổng doanh thu tương ứng với mỗi tháng. Tôi cần ouput dưới hình thức 12 cột tương ứng với mỗi tháng, trong đó sẽ có một hồ sơ duy nhất có bán hàng cho mỗi cột (tháng).Máy chủ SQL: chuyển đổi hàng thành cột

Trả lời

10

Bạn nên có một cái nhìn tại PIVOT để chuyển đổi hàng với các cột. Điều này ngăn chặn một tuyên bố chọn cho mỗi tháng. Một cái gì đó như thế này:

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

bạn nên hiển thị cú pháp INSERT trước năm 2008 –

+0

Có lẽ bạn đã đúng, mặc dù câu hỏi không đề cập đến phiên bản SQL Server. Cập nhật câu trả lời của tôi để thông báo cho người đọc về sự khác biệt cú pháp. –

+0

@sahil garg: Bạn có làm việc này không? –

2

Không khá ... nhưng công trình này cũng

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

Bạn có thể làm điều đó với OLAP. Here là một liên kết khác đến tài liệu MSDN về chủ đề này.

Với OLAP, bạn có thể tạo khối lập phương với thông tin bạn có, với bố cục bạn cần.

Nếu bạn không muốn đi theo cách đó, bạn sẽ phải tạo bảng tóm tắt bằng .NET, Java, TransacSQL hoặc ngôn ngữ ưa thích của bạn để thao tác dữ liệu SQLServer.

2

Đây là cách thay thế để viết trục cung cấp cho bạn nhiều quyền kiểm soát hơn (đặc biệt là trên các tên cột). Việc tạo SQL động cũng dễ dàng hơn một chút.

Nó tương tự như câu trả lời của Robin, nhưng có lợi thế là chỉ đánh bảng một lần:

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; 

tôi đã làm một số điều tra, và nó có vẻ như các nhà điều hành trục mới chỉ là đường cú pháp cho loại truy vấn . Các kế hoạch truy vấn cuối cùng trông giống hệt nhau.

Là một điều thú vị sang một bên, toán tử tháo rời dường như cũng chỉ là đường cú pháp. Ví dụ:

Nếu bạn có một bảng như:

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

Bạn có thể viết:

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

Và lấy dữ liệu unpivoted ...

0

Để dễ dàng transpose cột thành hàng với tên của nó, bạn nên sử dụng XML. Trong blog của tôi, tôi đã mô tả điều này với ví dụ: Link

Các vấn đề liên quan