Grouping Sets:CUBE和ROLLUP從句

在上一篇文章裏我討論了SQL Server裏Grouping Sets的功能。從文中的例子能夠看到,經過簡單定義須要的分組集是很容易進行各自分組。但若是像從所給的列集裏想要有全部可能的分佈——即所謂的冪集(Power Set),要怎麼作呢?
html

固然,你能夠用grouping set的語法功能來手動生成冪集,但那須要寫一大堆的代碼。所以今天我向你展現下grouping set功能支持的2個從句:CUBEROLLUP從句。sql

CUBE從句

使用CUBE從句,對於提供的列集,你能夠生成全部可能的分組集。這就是所謂的冪集。當你有3列:a,b,和c。CUBE(a,b,c會爲你生成下列分組:數據庫

  • (a,b,c)
  • (a,b)
  • (b,c)
  • (a)
  • (b)
  • (c)
  • ()

下列查詢對CustomerID, SalesPersonID和YEAR(OrderDate) 列經過上週介紹的grouping set功能手工生成冪集。 spa

 1 -- Calculates the power set of CustomerID, SalesPersonID, YEAR(OrderDate)
 2 SELECT
 3     CustomerID, 
 4     SalesPersonID, 
 5     YEAR(OrderDate) AS 'OrderYear', 
 6     SUM(TotalDue) AS 'TotalDue'
 7 FROM Sales.SalesOrderHeader
 8 WHERE SalesPersonID IS NOT NULL
 9 GROUP BY GROUPING SETS
10 (
11     (CustomerID, SalesPersonID, YEAR(OrderDate)),
12     (CustomerID, SalesPersonID),
13     (CustomerID, YEAR(OrderDate)),
14     (SalesPersonID, YEAR(OrderDate)),
15     (CustomerID),
16     (SalesPersonID),
17     (YEAR(OrderDate)),
18     ()
19 )
20 GO

從代碼裏能夠看到,你必須指定每一個可能的組合。所以用簡單的需求寫出這樣的查詢是個很困難的,笨重的工做。若是你使用CUBE從句而不是指定各個分組集的話,事情就變得簡單多了。咱們來看下面的代碼。code

 1 -- Calculates the power set of CustomerID, SalesPersonID, YEAR(OrderDate) with the CUBE subclause
 2 SELECT
 3     CustomerID, 
 4     SalesPersonID, 
 5     YEAR(OrderDate) AS 'OrderYear', 
 6     SUM(TotalDue) AS 'TotalDue'
 7 FROM Sales.SalesOrderHeader
 8 WHERE SalesPersonID IS NOT NULL
 9 GROUP BY CUBE(CustomerID, SalesPersonID, YEAR(OrderDate))
10 GO

從代碼裏能夠看到,你只要指定列,SQL Server自己就會生成它的冪集。於第一次列出的代碼,這個代碼簡單,精煉不少。 htm

ROLLUP從句

CUBE從句外,自SQL Server 2008起,SQL Server也支持ROLLUP從句。使用ROLLUP從句你能夠定義冪集的子集。ROLLUP從句也假設各個列間的層級。當你有3列:a,b,和c。當你使用ROLLUP(a,b,c),它會生成下列分組集:blog

  • (a,b,c
  • (a,b)
  • (a)
  • ()

從這些獨立的分組集,你很容易看到在這些列之間有個層級。咱們換用CustomerID, SalesPersonID和YEAR(OrderDate) 列,這裏你就能夠得到這類分析查詢的實現思路。這是SSAS(SQL Server分析服務)的窮人作法。咱們來看下列使用ROLLUP從句的查詢: get

-- Calculates the following grouping sets:
-- => (OrderYear, OrderMonth, OrderDay)
-- => (OrderYear, OrderMonth)
-- => (OrderYear)
-- => ()
SELECT
    YEAR(OrderDate) AS 'OrderYear', 
    MONTH(OrderDate) AS 'OrderMonth',
    DAY(OrderDate) AS 'OrderDay',
    SUM(TotalDue) AS 'TotalDue'
FROM Sales.SalesOrderHeader
WHERE SalesPersonID IS NOT NULL
GROUP BY ROLLUP(YEAR(OrderDate), MONTH(OrderDate), DAY(OrderDate))
GO

這個查詢的輸出給你下列各自分組集: 數據分析

  • (OrderYear, OrderMonth, OrderDay)
  • (OrderYear, OrderMonth)
  • (OrderYear)
  • ()

ROLLUP從句有很是簡單的語法,但對於數據分析來講你的返回結果是很是強大的。 it

小結

我但願你對今天文章裏,自SQL Server 2008引入的grouping sets功能裏的CUBE和ROLLUP子句的介紹有所收穫。有空的話,不要吝嗇你的留言,告訴我你是否已經在你本身的數據庫裏使用這些從句,或者你是否定爲在你的環境裏它們是有用的。

感謝關注!

參考文章:

https://www.sqlpassion.at/archive/2014/09/22/grouping-sets-the-cube-and-rollup-subclauses/

相關文章
相關標籤/搜索