分組原理(GROUP BY子句)5:分組集的笛卡爾積及其他運算
若覺得本文寫得還可以,請多多關注本人所作書籍《C++語法詳解》電子工業出版社出版,作者 黃勇
本文爲原創文章,轉載請註明出處,或註明轉載自“黃邦勇帥(原名:黃勇)
八、分組集的笛卡爾積及其他運算
1、分組集是分組的集合,在SQL Server中,支持對分組集的笛卡爾積運算,比如,集合A的屬性集爲(a1, a2, a3),集合B的屬性集爲(b1, b2),則集合A與B的笛卡爾積A × B爲
A × B = { (a1,b1), (a1, b2), (a2, b1), (a2, b2), (a3, b1), (a3, b2) }
2、SQL Server對分組集執行笛卡爾積運算的方法如下:
在同一個GROUP BY子句中,當使用逗號分隔多個GROUPING SETS子句、ROLLUP從屬子句,CUBE從屬子句時,執行的便是笛卡爾積運算,當含有ROLLUP、CUBE從屬子句時,應把其轉換爲GROUPING SETS子句後再進行計算。
示例5.07:分組集的笛卡爾積運算
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS(a,b),GROUPING SETS (c,d) --語句1
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,c),(a,d),(b,c),(b,d)) --語句2=語句1
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,b),(b,c)),GROUPING SETS ((c,d)) --語句3
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,b,c,d),(b,c,d)) --語句4=語句3
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,b),(b,c)),GROUPING SETS (c,d) --語句5
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,b,c),(a,b,d),(b,c),(b,c,d)) --語句6=語句5
示例5.08:含CUBE或ROLLUP時的笛卡爾積運算
SELECT a,b,c,d FROM T4 GROUP BY CUBE((a,b),(b,c)),ROLLUP(c,d) --語句7
--把以上語句轉換爲GROUPING SETS之後再進行集合運算
SELECT a,b,c,d FROM T4 GROUP BY --與語句7等效的GROUPING SETS語句
GROUPING SETS((a,b,c),(a,b),(b,c),()),GROUPING SETS((c,d),(c),())
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS( --語句7的笛卡爾積,注意:重複結果集不能刪除 (a,b,c,d),(a,b,c),(a,b,c),(a,b,c,d),(a,b,c),(a,b),(b,c,d),(b,c),(b,c),(c,d),(c),())
3、注意:在GROUPING SETS子句、ROLLUP從屬子句,CUBE從屬子句中指定的重複列,是不能刪除的,刪除後將得到不同的結果,比如
GROUPING SETS( (a,b ), (a,b)) 與 GROUPING SETS ( (a,b) )
是不同的,前者會輸出兩個由(a, b)產生的分組集,後者將只輸出一個由(a, b)產生的分組集,再如
CUBE( (a,b), (a,b) ) 與 CUBE( (a, b) )
是不相同的,前者與GROUPING SETS( (a,b), (a,b), (a, b), ())相同,後者與GROUPING SETS( (a,b), () )相同
4、SQL Server還支持類似乘法分配律的運算,即形如 a × c + b × c = (a + b) × c,具體應用於SQL Server中時,就是指可把相同的元素提取出來,然後再執行笛卡爾積運算,比如GROUPING SETS((a,b),(b,c))等於GROUPING SETS ( (a), © ), GROUPING SETS ( (b) )
5、GROUPING SETS選項可以把兩個或多個ROLLUP子句或CUBE子句組合在一起,其最終結果是單個的ROLLUP子句或CUBE子句的UNION ALL運算,比如
SELECT a, b FROM T4 GROUP BY GROUPING SETS( ROLLUP(a, b), CUBE(a, b));
與以下UNION ALL查詢是等同的
SELECT a, b FROM T4 GROUP BY CUBE(a,b)
UNION ALL
SELECT a, b FROM T4 GROUP BY ROLLUP(a, b)
6、當CUBE或ROLLUP位於GROUPING SETS中,需要把CUBE或ROLLUP展開爲GROUPINT SETS表示的分組集時,此時不再需要使用GROUPING SETS關鍵字,比如,以下語句1和語句2是等效的
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS( ROLLUP(a,b),ROLLUP(c,d)); --語句1
SELECT a,b,c,d FROM T4 GROUP BY GROUPING SETS((a,b),(a),(),(c,d),(c),()) --語句2
下面爲其推導過程
語句1與以下語句等效
select NULL as a,NULL as b,c,d from T4 GROUP BY ROLLUP(c,d) --語句3
union all
select a,b,NULL AS c,NULL as d from T4 GROUP BY ROLLUP(a,b)
語句3與以下語句等效
select NULL as a,NULL as b,c,d from T4 GROUP BY GROUPING SETS((c,d),(c),()) --語句4
union all
select a,b,NULL AS c,NULL as d from T4 GROUP BY GROUPING SETS((a,b),(a),())
語句4與以下語句等效
select NULL as a,NULL as b,c,d from T4 GROUP BY c,d --語句5
union all
select NULL as a,NULL as b,c,NULL as d from T4 GROUP BY c
union all
select NULL as a,NULL as b,NULL as c,NULL as d from T4 GROUP BY ()
union all
select a,b,NULL AS c,NULL as d from T4 GROUP BY a,b
union all
select a,NULL AS b,NULL AS c,NULL as d from T4 GROUP BY a
union all
select NULL AS a,NULL AS b,NULL AS c,NULL as d from T4 GROUP BY ()
語句5與最終結果等效,即等效於語句2
7、SQL Server目前還不支持減法之類的運算,即不支持從CUBE(a, b, c, d)中減去GROUPING SETS ( (a, b), (c, d)) 之類的運算,該類型運算可使用EXCEPT或其他技術實現。
8、注意:GROUPING SETS選項,不會消除SELECT語句輸出的重複行。
作者:黃邦勇帥(原名:黃勇)