CUBE 和 ROLLUP 之間的具體區別

ROLLUP 運算符生成的結果集類似於 CUBE 運算符生成的結果集。

下面是 CUBE 和 ROLLUP 之間的具體區別:

CUBE 生成的結果集顯示了所選列中值的所有組合的聚合。
ROLLUP 生成的結果集顯示了所選列中值的某一層次結構的聚合。
ROLLUP 優點:

(1)ROLLUP 返回單個結果集,而 COMPUTE BY 返回多個結果集,而多個結果集會增加應用程序代碼的複雜性。
(2)ROLLUP 可以在服務器遊標中使用,而 COMPUTE BY 則不可以。
(3)有時,查詢優化器爲 ROLLUP 生成的執行計劃比爲 COMPUTE BY 生成的更爲高效。

下面對比一下GROUP BY 、CUBE 和 ROLLUP後的結果

創建表:

CREATE TABLE DEPART
(部門 char(10),員工 char(6),工資 int)

INSERT INTO DEPART SELECT ‘A’,’ZHANG’,100
INSERT INTO DEPART SELECT ‘A’,’LI’,200
INSERT INTO DEPART SELECT ‘A’,’WANG’,300
INSERT INTO DEPART SELECT ‘A’,’ZHAO’,400
INSERT INTO DEPART SELECT ‘A’,’DUAN’,500
INSERT INTO DEPART SELECT ‘B’,’DUAN’,600
INSERT INTO DEPART SELECT ‘B’,’DUAN’,700

部門 員工 工資

A ZHANG 100
A LI 200
A WANG 300
A ZHAO 400
A DUAN 500
B DUAN 600
B DUAN 700

(1)GROUP BY

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工

結果:

A DUAN 500
B DUAN 1300
A LI 200
A WANG 300
A ZHANG 100
A ZHAO 400

(2)ROLLUP

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工 WITH ROLLUP

結果如下:

A DUAN 500
A LI 200
A WANG 300
A ZHANG 100
A ZHAO 400
A NULL 1500
B DUAN 1300
B NULL 1300
NULL NULL 2800

ROLLUP結果集中多了三條彙總信息:即部門A的合計,部門B的合計以及總合計。其中將部門B中的DUAN合計。

等價於下列SQL語句

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工
union
SELECT 部門,’NULL’,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門
union
SELECT ‘NULL’,’NULL’,SUM(工資)AS TOTAL
from DEPART

結果:

A DUAN 500
A LI 200
A NULL 1500
A WANG 300
A ZHANG 100
A ZHAO 400
B DUAN 1300
B NULL 1300
NULL NULL 2800

(3)CUBE

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工 WITH CUBE

結果:

A DUAN 500
A LI 200
A WANG 300
A ZHANG 100
A ZHAO 400
A NULL 1500
B DUAN 1300
B NULL 1300
NULL NULL 2800
NULL DUAN 1800
NULL LI 200
NULL WANG 300
NULL ZHANG 100
NULL ZHAO 400

CUBE的結果集是在 ROLLUP結果集的基礎上多了5行,這5行相當於在ROLLUP結果集上在union 上以員工 (即CUBE)爲 GROUP BY的結果。

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工 WITH CUBE

等價於下列的SQL語句:

SELECT 部門,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 部門,員工 WITH ROLLUP

union

SELECT ‘NULL’,員工,SUM(工資)AS TOTAL
from DEPART
GROUP BY 員工

結果:

NULL NULL 2800
A NULL 1500
A DUAN 500
A LI 200
A WANG 300
A ZHANG 100
A ZHAO 400
B NULL 1300
B DUAN 1300
NULL DUAN 1800
NULL LI 200
NULL WANG 300
NULL ZHANG 100
NULL ZHAO 400


rollup 舉例


這裏介紹sql server2005裏面的一個使用實例:

CREATE TABLE tb(province nvarchar(10),city nvarchar(10),score int)

INSERT tb SELECT ‘陝西’,’西安’,3

UNION ALL SELECT ‘陝西’,’安康’,4

UNION ALL SELECT ‘陝西’,’漢中’,2

UNION ALL SELECT ‘廣東’,’廣州’,5

UNION ALL SELECT ‘廣東’,’珠海’,2

UNION ALL SELECT ‘廣東’,’東莞’,3

UNION ALL SELECT ‘江蘇’,’南京’,6

UNION ALL SELECT ‘江蘇’,’蘇州’,1

GO

1、 只有一個彙總

select province as 省,sum(score) as 分數 from tb group by province with rollup

結果:

廣東 10

江蘇 7

陝西 9

NULL 26

select case when grouping(province)=1 then ‘合計’ else province end as 省,sum(score) as 分數 from tb group by province with rollup

結果:

廣東 10

江蘇 7

陝西 9

合計 26

2、兩級,中間小計最後彙總

select province as 省,city as 市,sum(score) as 分數 from tb group by province,city with rollup

結果:

廣東 東莞 3

廣東 廣州 5

廣東 珠海 2

廣東 NULL 10

江蘇 南京 6

江蘇 蘇州 1

江蘇 NULL 7

陝西 安康 4

陝西 漢中 2

陝西 西安 3

陝西 NULL 9

NULL NULL 26

select province as 省,city as 市,sum(score) as 分數,grouping(province) as g_p,grouping(city) as g_c from tb group by province,city with rollup

結果:

廣東 東莞 3 0 0

廣東 廣州 5 0 0

廣東 珠海 2 0 0

廣東 NULL 10 0 1

江蘇 南京 6 0 0

江蘇 蘇州 1 0 0

江蘇 NULL 7 0 1

陝西 安康 4 0 0

陝西 漢中 2 0 0

陝西 西安 3 0 0

陝西 NULL 9 0 1

NULL NULL 26 1 1

select case when grouping(province)=1 then ‘合計’ else province end 省,

case when grouping(city)=1 and grouping(province)=0 then ‘小計’ else city end 市,

sum(score) as 分數

from tb group by province,city with rollup

結果:

廣東 東莞 3

廣東 廣州 5

廣東 珠海 2

廣東 小計 10

江蘇 南京 6

江蘇 蘇州 1

江蘇 小計 7

陝西 安康 4

陝西 漢中 2

陝西 西安 3

陝西 小計 9

合計 NULL 26


cube舉例


使用cube操作符時,最多可以有10個分組表達式

在cube中不能使用all關鍵字

舉例

例如,簡單表 Inventory 包含下列數據:

Item Color Quantity


Table Blue 124

Table Red 223

Chair Blue 101

Chair Red 210

以下查詢將返回一個結果集,其中包含 DE>ItemDE> 和 DE>ColorDE> 的所有可能組合的 DE>QuantityDE> 小計:

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

此行報告了在 DE>ItemDE> 維度中包含 DE>ChairDE> 值的所有行的小計。對 DE>ColorDE> 維度返回了 DE>nullDE> 值,用以表示該行報告的聚合包括 DE>ColorDE> 維度爲任意值的行。

Table (null) 347.00

這一行類似,但報告的是 DE>ItemDE> 維度中包含 DE>TableDE> 值的所有行的小計。

(null) (null) 658.00

這一行報告了多維數據集的總計。DE>ItemDE> 和 DE>ColorDE> 維度都包含 DE>nullDE> 值。這表示此行中彙總了這兩個維度的所有值。

(null) Blue 225.00

(null) Red 433.00

這兩行報告了 DE>ColorDE> 維度的小計。兩行中的 DE>ItemDE> 維度值都是 DE>nullDE>,表示聚合數據來自 DE>ItemDE> 維度爲任意值的行。

使用 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

此 DE>SELECTDE> 語句返回的結果集既顯示了 DE>ItemDE> 中每個值的小計,也顯示了 DE>ItemDE> 中所有值的總計:

Item QtySum


Chair 311.00

Table 347.00

ALL 658.00

包含具有多個維度的 CUBE 的 SELECT 語句可生成大型結果集,因爲這些語句會爲所有維度中各值的所有組合都生成相應的行。這些大型結果集包含的數據可能會過多而不易於閱讀和理解。此問題的一種解決辦法是將 DE>SELECTDE> 語句放入視圖中:

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)

轉載自:http://www.cnblogs.com/flysun0311/archive/2011/03/10/1979414.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章