用 CUBE 匯總數據
CUBE 運算符生成的結果集是多維數據集。多維數據集是事實數據的擴展,事實數據即記錄個別事件的數據。擴展建立在用戶打算分析的列上。這些列被稱為維。多維數據集是一個結果集,其中包含了各維度的所有可能組合的交叉表格。
CUBE 運算符在 SELECT 語句的 GROUP BY 子句中指定。該語句的選擇列表應包含維度列和聚合函數表達式。GROUP BY 應指定維度列和關鍵字 WITH CUBE。結果集將包含維度列中各值的所有可能組合,以及與這些維度值組合相匹配的基礎行中的聚合值。
例如,一個簡單的表 Inventory 中包含:
Item???????????????? Color??????????????? Quantity??????????????????
-------------------- -------------------- --------------------------
Table??????????????? Blue???????????????? 124???????????????????????
Table??????????????? Red????????????????? 223???????????????????????
Chair??????????????? Blue???????????????? 101???????????????????????
Chair??????????????? Red????????????????? 210???????????????????????
下列查詢返回的結果集中,將包含 Item 和 Color 的所有可能組合的 Quantity 小計:
SELECT Item, Color, SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH CUBE
下面是結果集:
Item???????????????? Color??????????????? QtySum????????????????????
-------------------- -------------------- --------------------------
Chair??????????????? Blue???????????????? 101.00????????????????????
Chair??????????????? Red????????????????? 210.00????????????????????
Chair??????????????? (null)?????????????? 311.00????????????????????
Table??????????????? Blue???????????????? 124.00????????????????????
Table??????????????? Red????????????????? 223.00????????????????????
Table??????????????? (null)?????????????? 347.00????????????????????
(null)?????????????? (null)?????????????? 658.00????????????????????
(null)?????????????? Blue???????????????? 225.00????????????????????
(null)?????????????? Red????????????????? 433.00????????????????????
我們著重考查下列各行:
Chair??????????????? (null)?????????????? 311.00????????????????????
這一行報告了 Item 維度中值為 Chair 的所有行的小計。對 Color 維度返回了 NULL 值,表示該行所報告的聚合包括 Color 維度為任意值的行。
Table??????????????? (null)?????????????? 347.00????????????????????
這一行類似,但報告的是 Item 維度中值為 Table 的所有行的小計。
(null)?????????????? (null)?????????????? 658.00????????????????????
這一行報告了多維數據集的總計。Item 和 Color 維度的值都是 NULL,表示兩個維度中的所有值都匯總在該行中。
(null)?????????????? Blue???????????????? 225.00????????????????????
(null)?????????????? Red????????????????? 433.00????????????????????
這兩行報告了 Color 維度的小計。兩行中的 Item 維度值都是 NULL,表示聚合數據來自 Item 維度為任意值的行。
使用 GROUPING 區分空值
CUBE 操作所生成的空值帶來一個問題:如何區分 CUBE 操作所生成的 NULL 值和從實際數據中返回的 NULL 值?這個問題可用 GROUPING 函數解決。如果列中的值來自事實數據,則 GROUPING 函數返回 0;如果列中的值是 CUBE 操作所生成的 NULL,則返回 1。在 CUBE 操作中,所生成的 NULL 代表全體值。可將 SELECT 語句寫成使用 GROUPING 函數將所生成的 NULL 替換為字符串 ALL。因為事實數據中的 NULL 表明數據值未知,所以 SELECT 語句還可譯碼為返回字符串 UNKNOWN 替代來自事實數據的 NULL。例如:
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Item, 'UNKNOWN')
?????? END AS Item,
?????? CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Color, 'UNKNOWN')
?????? END AS Color,
?????? SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH CUBE
多維數據集
CUBE 運算符可用于生成 n 維的多維數據集,即具有任意數目維度的多維數據集。只有一個維度的多維數據集可用于生成合計,例如:
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Item, 'UNKNOWN')
?????? END AS Item,
?????? SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item WITH CUBE
GO
此 SELECT 語句返回的結果集既顯示了 Item 中每個值的小計,也顯示了 Item 中所有值的總計:
Item???????????????? QtySum????????????????????
-------------------- --------------------------
Chair??????????????? 311.00????????????????????
Table??????????????? 347.00????????????????????
ALL????????????????? 658.00????????????????????
包含帶有許多維度的 CUBE 的 SELECT 語句可能生成很大的結果集,因為這些語句會為所有維度中值的所有組合生成行。這些大結果集包含的數據可能過多而不易于閱讀和理解。這個問題有一種解決辦法是將 SELECT 語句放在視圖中:
CREATE VIEW InvCube AS
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Item, 'UNKNOWN')
?????? END AS Item,
?????? CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Color, 'UNKNOWN')
?????? END AS Color,
?????? SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH CUBE
然后即可用該視圖來只查詢您感興趣的維度值:
SELECT *
FROM InvCube
WHERE Item = 'Chair'
? AND Color = 'ALL'
Item???????????????? Color??????????????? QtySum????????????????????
-------------------- -------------------- --------------------------
Chair??????????????? ALL????????????????? 311.00????????????????????
(1 row(s) affected)
用 ROLLUP 匯總數據
在生成包含小計和合計的報表時,ROLLUP 運算符很有用。ROLLUP 運算符生成的結果集類似于 CUBE 運算符所生成的結果集。有關更多信息,請參見用 CUBE 匯總數據。
CUBE 和 ROLLUP 之間的區別在于:
CUBE 生成的結果集顯示了所選列中值的所有組合的聚合。
ROLLUP 生成的結果集顯示了所選列中值的某一層次結構的聚合。
例如,簡單表 Inventory 中包含:
Item???????????????? Color??????????????? Quantity??????????????????
-------------------- -------------------- --------------------------
Table??????????????? Blue???????????????? 124???????????????????????
Table??????????????? Red????????????????? 223???????????????????????
Chair??????????????? Blue???????????????? 101???????????????????????
Chair??????????????? Red????????????????? 210???????????????????????
下列查詢將生成小計報表:
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Item, 'UNKNOWN')
?????? END AS Item,
?????? CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
??????????? ELSE ISNULL(Color, 'UNKNOWN')
?????? END AS Color,
?????? SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP
Item???????????????? Color??????????????? QtySum????????????????????
-------------------- -------------------- --------------------------
Chair??????????????? Blue???????????????? 101.00????????????????????
Chair??????????????? Red????????????????? 210.00????????????????????
Chair??????????????? ALL????????????????? 311.00????????????????????
Table??????????????? Blue???????????????? 124.00????????????????????
Table??????????????? Red????????????????? 223.00????????????????????
Table??????????????? ALL????????????????? 347.00????????????????????
ALL????????????????? ALL????????????????? 658.00????????????????????
(7 row(s) affected)
如果查詢中的 ROLLUP 關鍵字更改為 CUBE,那么 CUBE 結果集與上述結果相同,只是在結果集的末尾還會返回下列兩行:
ALL????????????????? Blue???????????????? 225.00????????????????????
ALL????????????????? Red????????????????? 433.00????????????????????
CUBE 操作為 Item 和 Color 中值的可能組合生成行。例如,CUBE 不僅報告與 Item 值 Chair 相組合的 Color 值的所有可能組合(Red、Blue 和 Red + Blue),而且報告與 Color 值 Red 相組合的 Item 值的所有可能組合(Chair、Table 和 Chair + Table)。
對于 GROUP BY 子句中右邊的列中的每個值,ROLLUP 操作并不報告左邊一列(或左邊各列)中值的所有可能組合。例如,ROLLUP 并不對每個 Color 值報告 Item 值的所有可能組合。
ROLLUP 操作的結果集具有類似于 COMPUTE BY 所返回結果集的功能;然而,ROLLUP 具有下列優點:
ROLLUP 返回單個結果集;COMPUTE BY 返回多個結果集,而多個結果集會增加應用程序代碼的復雜性。
ROLLUP 可以在服務器游標中使用;COMPUTE BY 不可以。
有時,查詢優化器為 ROLLUP 生成的執行計劃比為 COMPUTE BY 生成的更為高效。
用 COMPUTE 和 COMPUTE BY 匯總數據
提供 COMPUTE 和 COMPUTE BY 是為了向后兼容。請改為使用下列組件:
Microsoft? SQL Server? 2000 Analysis Services 和用于 Analysis Services 的 OLE DB 或 Microsoft ActiveX? 數據對象(多維)(ADO MD) 一起使用。有關更多信息,請參見 Microsoft SQL Server? 2000 Analysis Services。
ROLLUP 運算符。有關更多信息,請參見用 ROLLUP 匯總數據。
COMPUTE BY 子句使您得以用同一 SELECT 語句既查看明細行,又查看匯總行。可以計算子組的匯總值,也可以計算整個結果集的匯總值。
COMPUTE 子句需要下列信息:
可選的 BY 關鍵字,該關鍵字可按對一列計算指定的行聚合。
行聚合函數名稱;例如,SUM、AVG、MIN、MAX 或 COUNT。
要對其執行行聚合函數的列。
COMPUTE 生成的結果集
COMPUTE 所生成的匯總值在查詢結果中顯示為分離的結果集。包括 COMPUTE 子句的查詢的結果類似于控制中斷報表,即匯總值由指定的組(或稱中斷)控制的報表。可以為各組生成匯總值,也可以對同一組計算多個聚合函數。
當 COMPUTE 帶有可選的 BY 子句時,符合 SELECT 條件的每個組都有兩個結果集:
每個組的第一個結果集是明細行集,其中包含該組的選擇列表信息。
每個組的第二個結果集有一行,其中包含該組的 COMPUTE 子句中所指定的聚合函數的小計。
當 COMPUTE 不帶可選的 BY 子句時,SELECT 語句有兩個結果集:
每個組的第一個結果集是包含選擇列表信息的所有明細行。
第二個結果集有一行,其中包含 COMPUTE 子句中所指定的聚合函數的合計。
COMPUTE 用法示例
下列 SELECT 語句使用簡單 COMPUTE 子句生成 titles 表中 price 及 advance 的求和總計:
USE pubs
SELECT type, price, advance
FROM titles
ORDER BY type
COMPUTE SUM(price), SUM(advance)
下列查詢在 COMPUTE 子句中加入可選的 BY 關鍵字,以生成每個組的小計:
USE pubs
SELECT type, price, advance
FROM titles
ORDER BY type
COMPUTE SUM(price), SUM(advance) BY type
此 SELECT 語句的結果用 12 個結果集返回,六個組中的每個組都有兩個結果集。每個組的第一個結果集是一個行集,其中包含選擇列表中所請求的信息。每個組的第二個結果集包含 COMPUTE 子句中兩個 SUM 函數的小計。
?
說明? 一些實用工具(如 osql)顯示多個小計或合計聚合匯總的方式可能會使用戶以為每個小計都是結果集中的單獨一行。這是由于該實用工具設置輸出格式的方式;小計或合計聚合返回時單獨占用一行。其它應用程序(如 SQL 查詢分析器)將多個聚合設置在同一行。
比較 COMPUTE 和 GROUP BY
COMPUTE 和 GROUP BY 之間的區別匯總如下:
GROUP BY 生成單個結果集。每個組都有一個只包含分組依據列和顯示該組子聚合的聚合函數的行。選擇列表只能包含分組依據列和聚合函數。
COMPUTE 生成多個結果集。一類結果集包含每個組的明細行,其中包含選擇列表中的表達式。另一類結果集包含組的子聚合,或 SELECT 語句的總聚合。選擇列表可包含除分組依據列或聚合函數之外的其它表達式。聚合函數在 COMPUTE 子句中指定,而不是在選擇列表中。
下列查詢使用 GROUP BY 和聚合函數;該查詢將返回一個結果集,其中每個組有一行,該行中包含該組的聚合小計:
USE pubs
SELECT type, SUM(price), SUM(advance)
FROM titles
GROUP BY type
?
說明? 在 COMPUTE 或 COMPUTE BY 子句中,不能包含 ntext、text 或 image 數據類型。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
