Sql Server中不經常使用的表運算符之PIVOT

PIVOT是SQL Server2005新添加的一個表運算符,做用在於將行轉爲列。sql

先來看看他的基本語法:函數

來自http://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspxspa

SELECT <非透視的列>,
    [第一個透視的列] AS <列名稱>,
    [第二個透視的列] AS <列名稱>,
    ...
    [最後一個透視的列] AS <列名稱>,
FROM
    (<生成數據的 SELECT 查詢>)
    AS <源查詢的別名>
PIVOT
(
    <聚合函數>(<要聚合的列>)
FOR
[<包含要成爲列標題的值的列>]
    IN ( [第一個透視的列], [第二個透視的列],
    ... [最後一個透視的列])
) AS <透視表的別名>
<可選的 ORDER BY 子句>;

 看到這一坨,我已經暈了,因此仍是用一個實際的列子來理解。code

假設有以下order表blog

下面這個查詢將返回不一樣城市,地區的消費者的訂單數排序

SELECT
    City,--可選非透視列
    Region,--可選非透視列
    C001,--透視列
    C002,--透視列
    C003--透視列
FROM 
(
    SELECT
        City,
        Region,
        CustomId,
        OrderId
        FROM dbo.[Order]
)AS OrderTable--源表
PIVOT (
    COUNT(--聚合函數
            OrderID--要聚合的列
        )
        FOR CustomId--要成爲標題值的列
            IN(
                [C001],--透視列
                [C002],--透視列
                [C003]--透視列
            )
        )
AS PivoTTable
ORDER BY City DESC--可選Order by

結果以下get

PIVOT將按一下三個步驟處理源表it

1.隱式分組io

源表中選出了四列,其中的兩列做爲PIVOT的輸入參數:OrderID--要聚合的列,CustomId--要成爲標題值的列編譯

剩下的兩列將做爲源表的隱式分組,源表查詢將會轉換爲以下查詢

SELECT
    City,
    Region,
    OrderID,
    CustomID
FROM dbo.[Order]
    GROUP BY City,Region

此時這個查詢沒法經過編譯,由於咱們尚未對OrderID和CustomID進行聚合操做。

2.隔離值

這個階段將對透視列進行隔離,相似於下面的操做

SELECT
    City,
    Region,
    CASE WHEN CustomId ='C001' THEN OrderId END AS C001,
    CASE WHEN CustomId ='C002' THEN OrderId END AS C002,
    CASE WHEN CustomId ='C003' THEN OrderId END AS C003
    FROM dbo.[Order]
        GROUP BY City,Region

3.對每一個CASE表達式進行聚合操做,獲得最終查詢

SELECT
    City,
    Region,
    COUNT(CASE WHEN CustomId ='C001' THEN OrderId END) AS C001,
    COUNT(CASE WHEN CustomId ='C002' THEN OrderId END) AS C002,
    COUNT(CASE WHEN CustomId ='C003' THEN OrderId END) AS C003
    FROM dbo.[Order]
        GROUP BY City,Region
    ORDER BY City DESC--可選的排序操做

最後執行上面這個查詢,將獲得與使用PIVOT同樣的透視結果。

而隱式分組的列的行值將做爲透視行連同透視列一塊兒組成透視表。

相關文章
相關標籤/搜索