分组原理(GROUP BY子句)5:分组集的笛卡尔积及其他运算
若觉得本文写得还可以,请多多关注本人所作书籍《C++语法详解》电子工业出版社出版,作者 黄勇,网盘地址:
https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg
本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)
八、分组集的笛卡尔积及其他运算
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语句输出的重复行。
作者:黄邦勇帅(原名:黄勇)