一、介绍
Cube运算符的作用是自动对group by子句中列出的字段进行分组汇总运算。
Cube运算符生成的结果集是多维数据集。多维数据集是事实数据的扩展,事实数据即记录个别事件的数据。扩展建立在用户打算分析的列上,这些列称为维。多维数据集是一个结果集,其中包含了各维度的所有可能组合的交叉表格。
Cube运算符在SQL语句的Group by子句中指定。该语句的选择列表应包含维度列和聚合函数表达式。Group by应指定维度列和关键字 with cube。结果集将包含维度列中各值的所有可能组合,以及与这些维度值组合相匹配的基础行中的聚合值。
例如,一个简单的存货信息表中包含如下内容:
项目 |
颜色 |
质量 |
Table |
Blue |
124 |
Table |
Red |
223 |
Chair |
Blue |
101 |
Chair |
Red |
210 |
下列查询返回的结果集中,将包含项目和颜色的所有可能组合的质量总和,SQL语句如下:
Select 项目,颜色,sum(质量) as 总质量
From 存货表
Group by 项目,颜色 with cube
下面则是显示结果:
项目 |
颜色 |
总质量 |
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 |
二、实例讲解
创建表
CREATE TABLE [dbo].[tb_stuAchievement07](
[学生编号] [int] NULL,
[学生姓名] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[性别] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[语文] [int] NULL,
[代数] [int] NULL,
[几何] [int] NULL,
[英语] [int] NULL,
[班级] [char](10) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
输入数据如下图所示:
输入以下SQL语句:
select * from tb_stuAchievement07
select 班级,性别,avg(语文) as 语文平均成绩,
avg(代数) as 代数平均成绩,avg(几何) as 几何平均成绩,
avg(英语) as 英语平均成绩
from tb_stuAchievement07
group by 班级,性别
select 班级,性别,avg(语文) as 语文平均成绩,
avg(代数) as 代数平均成绩,avg(几何) as 几何平均成绩,
avg(英语) as 英语平均成绩
from tb_stuAchievement07
group by 班级,性别with cube
执行结果如下:
最后一张图数据解析如下:
查询的是二班的女生的各科平均成绩
查询的是二班的所有性别(男生和女生)的各科平均成绩
查询的是三班的所有性别(男生和女生)的各科平均成绩
查询的是所有班级所有性别的各科的平均成绩
查询的是所有班级的男生的的平均成绩
查询的是所有班级的男生的的平均成绩
综上,最后一张表中的‘null’并不是空值的意思,而是‘all’所有的意思。
使用 GROUPING 区分空值
CUBE 操作所生成的空值带来一个问题:如何区分 CUBE 操作所生成的 NULL 值和从实际数据中返回的 NULL 值?这个问题可用 GROUPING 函数解决。如果列中的值来自事实数据,则 GROUPING 函数返回 0;如果列中的值是 CUBE 操作所生成的 NULL,则返回 1。在 CUBE 操作中,所生成的 NULL 代表全体值。可将 SELECT 语句写成使用 GROUPING 函数将所生成的 NULL 替换为字符串 ALL。因为事实数据中的 NULL 表明数据值未知,所以 SELECT 语句还可译码为返回字符串 UNKNOWN 替代来自事实数据的 NULL。
select * from tb_stuAchievement07
select 班级,性别,avg(语文) as 语文平均成绩,
avg(代数) as 代数平均成绩,avg(几何) as 几何平均成绩,
avg(英语) as 英语平均成绩
from tb_stuAchievement07
group by 班级,性别
select case when (grouping(班级)=1) then 'all'
else isnull(班级,'UNKNOWN')
end as 班级,
case when (grouping(性别)=1) then 'all'
else isnull(性别,'UNKNOWN')
end as 性别,
avg(语文) as 语文平均成绩,
avg(代数) as 代数平均成绩,avg(几何) as 几何平均成绩,
avg(英语) as 英语平均成绩
from tb_stuAchievement07
group by 班级,性别with cube
执行结果如下: