2013年8月19日 星期一

[T-SQL]PIVOT兩欄甚至多欄的方法

        最近遇到一個報表的特殊需求,要將兩個欄位的列轉成欄(PIVOT),一般頂多處理一欄吧,這次要處理兩欄,而且轉置後,將會多出五十幾個欄位喔...@@

        基本上可以用CASE處理;也可以用PIVOT,雖然BOL上沒提到PIVOT可以多欄,實際上可以用多個PIVOT來做,但最後還要GROUP BY再SUM起來有點麻煩;也可以分別對兩個欄位各自PIVOT後,再JOIN起來,一樣可達到目的

        我在想說有沒有更好的方法,結果在網路上看到有人用PIVOT把多欄當一欄來做,超簡單的,我想都沒想到可以這樣用呢,就是先將多欄UNPIVOT成一欄,再PIVOT就OK啦


        這邊舉個PIVOT兩欄的例子


IF OBJECT_ID (N'dbo.tmpProduct', N'U') IS NOT NULL
     DROP TABLE dbo.tmpProduct;

CREATE TABLE dbo.tmpProduct(
     [SalesID] INT NULL,
     [ProductID] INT NULL,
     [Product] VARCHAR(32) NULL,
     [LocationID] INT NULL,
     [Location] VARCHAR(32) NULL,
     [Quantity] INT NULL,
     [Year] INT NULL,
);

INSERT dbo.tmpProduct
VALUES
(1,1,'Bikes',100,'TAIWAN',100,2013),
(2,2,'Clothing',100,'TAIWAN',50,2013),
(3,3,'Accessories',100,'TAIWAN',30,2013),
(4,1,'Bikes',300,'JAPAN',100,2012),
(5,2,'Clothing',300,'JAPAN',50,2012),
(6,3,'Accessories',200,'CHINA',30,2011),
(7,2,'Clothing',100,'TAIWAN',50,2011),
(8,3,'Accessories',200,'CHINA',30,2011);

SELECT * FROM dbo.tmpProduct ;



SELECT *
FROM (
     SELECT [Year],
              X.value,
              X.col
     FROM [dbo].[tmpProduct] C
     CROSS APPLY --CROSS APPLYUNPIVOT超簡單
       (
         VALUES
              (C.[Product] ,C.[Quantity]),
              (C.[Location] ,C.[Quantity])
        ) X (col,value)
) S
PIVOT (
     SUM([value]) FOR [col] IN ([Bikes],[Clothing],[Accessories],[TAIWAN],[CHINA],[JAPAN])
) AS P;



DROP TABLE  dbo.tmpProduct;

2 則留言:

  1. 再往外包一層 SELECT 語包, 如下:
    SELECT a.Year, ISNULL(a.Bikes,0), ISNULL(a.Clothing,0)...
    FROM ( SELECT .... AS P ) AS a

    回覆刪除