SQL中CUBE 用法
转自 http://www.cnblogs.com/dyufei/archive/2009/11/11/2573975.html
CUBE 运算符生成的结果集是多维数据集。多维数据集是事实数据(即记录个别事件的数据)的扩展。扩展是基于用户要分析的列建立的。这些列称为维度。多维数据集是结果集,其中包含各维度的所有可能组合的交叉表格。
CUBE 运算符在 SELECT 语句的 GROUP BY 子句中指定。该语句的选择列表包含维度列和聚合函数表达式。GROUP BY 指定了维度列和关键字 WITH CUBE。结果集包含维度列中各值的所有可能组合,以及与这些维度值组合相匹配的基础行中的聚合值。
cube将返回的更多的可能组合。如果在 group by 子句中有n个列或者是有n个表达式的话,sqlserver在结果集上会返回2的n-1次幂个可能组合。
注意:
使用cube操作符时,最多可以有10个分组表达式
在cube中不能使用all关键字
举例(来自MSDN)
例如,简单表 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)
SQL中CUBE 用法的更多相关文章
- SQL 中ROLLUP 用法
SQL 中ROLLUP 用法 ROLLUP 运算符生成的结果集类似于 CUBE 运算符生成的结果集. 下面是 CUBE 和 ROLLUP 之间的具体区别: CUBE 生成的结果集显示了所选列中值的所有 ...
- Sql 中Collate用法
今天查询sqlite的时候需要不区分大小写,查了下文档,需要使用collate nocase.顺便学习下collate的用法. collate在sql中是用来定义排序规则的.排序规则其实就是当比较两个 ...
- sql 中 exists用法
SQL中EXISTS的用法 比如在Northwind数据库中有一个查询为SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(S ...
- 数据库sql中distinct用法注意事项
在写sql中去重复等操作,需要用到distinct. 在使用distinct的时候要注意,尤其是在有行列转换的时候.要把sql运行出来看看是不是与你想要的结果一样. 通过自己试验,distinct有从 ...
- 详细的SQL中datediff用法
DATEDIFF 函数 [日期和时间] 功能返回两个日期之间的间隔. 语法DATEDIFF ( date-part, date-expression-1, date-expression-2 ) da ...
- Sql中CHARINDEX用法
CHARINDEX作用 写SQL语句我们经常需要判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEI ...
- SQL中ISNULL用法示例
ISNULLSQL查询示例SELECT ISNULL 使用指定的替换值替换 NULL. 语法 :ISNULL ( check_expression , replacement_val ...
- sql中table用法
for c in (select column_value from table(f_split(V_FileID, ','))) loop --若没有填写资格开始结束时间,则填入 select co ...
- SQL 中 HAVING 用法
现在 Student表有 如下数据 现需求如下: 查找每个老师的学生的平均年龄且平均年齿大于12 不使用 HAVING SELECT * FROM (SELECT TeacherID, AVG(Age ...
- SQL中的between and
"between xx and xx "在SQL中的用法 这个大家都很熟悉,但是当问到是否包含两端的值时,就有点儿不确定了.在W3School网站上,有这样的一段话: 参考:ht ...
随机推荐
- 【4】创建一个自己的Bootstrap模板
什么也不说了,直接贴上代码吧,哈哈 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta ch ...
- struts2处理.do后缀的请求
默认情况下,struts2是无法处理以.do为后缀的请求url的(默认情况下是.action或者不填,可以参见org.apache.struts2包下的default.properties文件). 但 ...
- hdu 5512 Pagodas 扩展欧几里得推导+GCD
题目链接 题意:开始有a,b两点,之后可以按照a-b,a+b的方法生成[1,n]中没有的点,Yuwgna 为先手, Iaka后手.最后不能再生成点的一方输: (1 <= n <= 2000 ...
- C++学习笔记——一只P转C的OIer的学习历程
2015-11-29 第一天接触c++(也不能这不说,看c++的程序也看了不少).重新找回了当时学pascal的感觉,从Hello World 开始写起,感觉自己的智商降低了,期间犯了各种弱智到不能再 ...
- delphi xe5 android 控制蓝牙
本文部分内容摘自: http://www.pclviewer.com/android/用以下代码中的接口实现控制蓝牙的开.关及详细信息 unit Androidapi.JNI.BluetoothAda ...
- SASS、COMPASS 安装指南
如果你还不知道 SASS 和 COMPASS 是什么,可以参看http://sass-lang.com 和http://compass-style.org,近期可能会更新一篇介绍性的入门教程,但 是本 ...
- HDU4521+线段树+dp
题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...
- Android 使控件各占屏幕的一半
在xml中将两个要占屏幕一半的控件都加上android:layout_weight="1": 注意:weight只能用在LinearLayout布局中. 在LinearLayout ...
- ruby 模块 的引入
module My NA="China" def My.set_name(name) @name=name end def My.get_name return @name end ...
- linux编译安装git
我的博客:www.while0.com 用的centos6.4中自带的git,版本为1.7.1,配置好github的sshkey后,clone下来的项目无法提交,提示: fatal: Unable t ...