天天看點

編寫

    PIVOT是新引入SQL Server 2005的運算符,它讓你能夠将行級資料旋轉成為清單資料,而不需要像先前版本的SQL Server一樣使用CASE語句。

CASE語句查詢

對于資料庫開發人員來說,将行級資料轉換為列級資料并不是什麼新東西。在SQL Server以前的版本裡,要獲得所需要的跨表格資料集就要用到一系列CASE語句和聚合查詢。雖然這種方式讓開發人員具有了對所傳回資料進行高度控制的能力,但是編寫出這些查詢是一件很麻煩的事情。

為了看一下這些CASE語句是如何使用的。我們需要一些測試資料。運作

清單A

裡的腳本能夠建立一個SalesHistory表格并把資料加載到表格裡。

現在我可以編寫一個基于CASE語句的PIVOT查詢。這個查詢的目标是按照年份将每件産品的銷售狀況集中起來,這些産品包括:BigScreen、PoolTable和Computer。每件産品自己的銷售資料都放在專用的列裡。

清單B

裡是CASE語句查詢的腳本。

這個查詢雖然很簡單,相對容易編寫,但是很繁複。你必須明确地為每個想要轉換成清單資料的行輸入一個CASE語句,這一點意思都沒有。如果有個程式能夠幫你自動完成這項任務就好了——這就是PIVOT運算符的作用之所在。

PIVOT

由于SQL Server 2005有了新的PIVOT運算符,就不再需要CASE語句和GROUP BY語句了。(每個PIVOT查詢都涉及某種類型的聚合,是以你可以忽略GROUP BY語句。)PIVOT運算符讓我們能夠利用CASE語句查詢實作相同的功能,但是你可以用更少的代碼就實作,而且看起來更漂亮。

清單C

是一個示例PIVOT查詢,它模仿的是我們的CASE語句查詢。

這個查詢的關鍵部分是PIVOT運算符後面的括号。在括号裡面,我們使用一個SUM聚合函數計算用FOR Product IN()語句列出的每個Product的SalePrice總和。這個語句可能看起來有點别扭,因為IN()語句的值沒有放在(')符号裡,它們是文本值。這些值事實上被當作ColumnNames對待,它們在最終的結果集裡被轉換成清單字段。

如果你運作這個查詢,得到的結果與我們從CASE語句查詢獲得的結果類似。但兩者的一個重要不同之處是,這個查詢仍然會為我們表格裡列出的每個行傳回一個行,這當然是不能令人滿意的;我們希望獲得一個直覺的表格清單,列出每年的銷售量。造成這種情況的問題在于我們一開始編寫PIVOT查詢的方式。

在這個查詢的SELECT語句中,我們隻是在SalesHistory清單裡簡單地列出了年,并為每個産品設定了一個字段。是以問題在于處理PIVOT語句的SELECT語句無法确定在PIVOT語句裡要使用哪一個列。PIVOT語句将分組應用到了所有的列,後者既不是旋轉字段也不是聚合字段。我們可以使用子查詢來實作滿意的結果。

清單D

是編寫好的查詢。這一小小的改動讓我們能夠用更少代碼模拟CASE語句查詢。

不足之處

PIVOT運算符在很多情況下都很有用,然而它還有一些不足之處。PIVOT運算符所提供的很多功能都要求你對旋轉成為列級資料的字段進行“寫死”。你可以利用動态TSQL語句編寫PIVOT查詢來解決這一問題,但是這還不是最理想的解決辦法。

使用PIVOT語句的另外一個潛在問題是你或許隻能在結果集裡聚合一個字段;而你利用CASE語句查詢可以聚合任意多的字段。

雖然這些潛在不足之處似乎可能成為阻礙使用新PIVOT運算符的障礙,但是它在TSQL開發人員的工具箱裡還是占有一席之地。