`

Oracle的rollup、cube、grouping sets函数

 
阅读更多
文章转自  http://blog.csdn.net/huang_xw/article/details/6402396

Oracle的group by除了基本用法以外,还有3种扩展用法,分别是rollup、cube、grouping sets。
1 rollup
假设有一个表test,有A、B、C、D、E5列。
如果使用group by rollup(A,B,C),首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。roll up的意思是“卷起”,这也可以帮助我们理解group by rollup就是对选择的列从右到左以一次少一列的方式进行grouping直到所有列都去掉后的grouping(也就是全表grouping),对于n个参数的rollup,有n+1次的grouping。以下2个sql的结果集是一样的:
Select A,B,C,sum(E) from test group by rollup(A,B,C)
[color=green][/color]

Select A,B,C,sum(E) from test group by A,B,C
union all
Select A,B,null,sum(E) from test group by A,B
union all
Select A,null,null,sum(E) from test group by A
union all
Select null,null,null,sum(E) from test

2 cube
cube的意思是立方,对cube的每个参数,都可以理解为取值为参与grouping和不参与grouping两个值的一个维度,然后所有维度取值组合的集合就是grouping的集合,对于n个参数的cube,有2^n次的grouping。如果使用group by cube(A,B,C),,则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作,一共是2^3=8次grouping。同rollup一样,也可以用基本的group by加上结果集的union all写出一个与group by cube结果集相同的sql:
Select A,B,C,sum(E) from test group by cube(A,B,C);


Select A,B,C,sum(E) from test group by A,B,C
union all
Select A,B,null,sum(E) from test group by A,B
union all
Select A,null,C,sum(E) from test group by A,C
union all
Select A,null,null,sum(E) from test group by A
union all
Select null,B,C,sum(E) from test group by B,C
union all
Select null,B,null,sum(E) from test group by B
union all
Select null,null,C,sum(E) from test group by C
union all
Select null,null,null,sum(E) from test;

3 grouping sets
grouping sets就是对参数中的每个参数做grouping,也就是有几个参数做几次grouping,例如使用group by grouping sets(A,B,C),则对(A),(B),(C)进行group by,如果使用group by grouping sets((A,B),C),则对(A,B),(C)进行group by。甚至grouping by grouping set(A,A)都是语法允许的,也就是对(A)进行2次group by,grouping sets的参数允许重复
4 总结
rollup        (N+1个分组方案)
cube         (2^N个分组方案)
grouping sets (自定义罗列出分组方案)
5 注意点
5.1 机制不同
在rollup和cube的说明中分别给出了用基本group by加结果集union all给出了结果集相同的sql,但这只是为了理解的方便而给出的sql,并不说明rollup和cube与基本group by加结果集union all等价。实际上两者的内部机制是安全不一样的,前者除了写法简洁以外,运行时不需多次扫描表,效率远比后者高。
5.2 集合可运算
3种扩展用法的参数可以是源表中的某一个具体的列,也可以是若干列经过计算而形成的一个新列(比如说A+B,A||B),也可以是这两种列的一个集合(例如(A+B,C)),对于grouping set更是特殊,可以是空集合(),表示对全表进行group by。
5.3 group by 与 rollup, cube组合使用
3)Group by的基本用法以及这3种扩展用法可以组合使用,也就是说可以出现group by A,rollup(A,B)这样的用法,oracle将对出现在group by中的每种用法的grouping列集合做笛卡尔积然后对其中的每一个元素做group by。这话说起来挺绕口,举例说明吧,group by A, rollup(A,B),基本用法的grouping集合是(A),rollup(A,B)的grouping集合是((A,B),(A),()),两个集合的笛卡尔积集合是((A,A,B),(A,A),(A)),所以会首先对(A,A,B)做group by,然后对(A,A)做group by,最后对(A)做group by。实际上对(A,A,B)做group by和对(A,B)做group by两者是完全等价的(group by A,A,B结果和group by A,B完全一样),同理对(A,A)做group by和对(A)做group by也是等价的。简化后的结果就是首先对(A,B)做group by,然后对(A)做group by,最后再对(A)做group by。下面给出两个等价的sql以便理解:
Select A,B,sum(E) from test1 group by A, rollup(A,B);


Select A,B,sum(E) from test1 group by A,B
Union all
Select A,null,sum(E) from test1 group by A
Union all
Select A,null,sum(E) from test1 group by A;

6 grouping()、grouping_id()、group_id()
6.1 grouping()
参数只有一个,而且必须为group by中出现的某一列,表示结果集的一行是否对该列做了grouping。对于对该列做了grouping的行而言,grouping()=0,反之为1;
6.2 grouping_id()
参数可以是多个,但必须为group by中出现的列。Grouping_id()的返回值其实就是参数中的每列的grouping()值的二进制向量,例如如果grouping(A)=1,grouping(B)=0,则grouping_id(A,B)的返回值就是二进制的10,转成10进制就是2。
6.3 group_id()
无参数。见上面的说明3),group by对某些列的集合会进行重复的grouping,而实际上绝大多数情况下对结果集中的这些重复行是不需要的,那就必须有办法剔出这些重复grouping的行。当结果集中有n条重复grouping而形成的行时,每行的group_id()分别是0,1,…,n,这样我们在条件中加入一个group_id()<1就可以剔出这些重复grouping的行了。
7 示例
7.1 建表与数据
SQL> create table test(department_id number, a varchar2(20), b varchar2(20));
Table created
SQL> insert into test values(10, 'A', 'B');
1 row inserted
SQL> commit;
Commit complete

7.2 查询语句
select department_id,
       a,
       b,
       grouping(department_id),
       grouping(a),
       grouping(b)
  from test
 group by rollup(department_id, a, b)
order by 4, 5, 6;
select department_id,
       a,
       b,
       grouping(department_id),
       grouping(a),
       grouping(b)
  from test
 group by cube(department_id, a, b)
order by 4, 5, 6;
分享到:
评论

相关推荐

    Oracle中用GROUPING SETS分组自定义汇总

    与`GROUP BY ROLLUP`和`GROUP BY CUBE`相比,`GROUPING SETS`更具有选择性,可以精确地控制生成的汇总组。`ROLLUP`生成所有可能的子集,而`CUBE`则生成所有可能的组合,这两者可能会产生大量的结果,尤其是在处理多...

    oracle中的grouping

    在Oracle数据库中,`GROUPING`函数被广泛应用于复杂的分组查询之中,尤其是在存储过程的开发中。本文将详细解释`GROUPING`函数的使用方法及其应用场景,并通过一个示例来帮助理解其工作原理。 #### 一、`GROUPING`...

    《Pro Oracle SQL》Chapter7 Advanced Grouping -- 7.5Putting CUBE To Work

    因此,为了优化性能和减少不必要的结果,我们可能需要配合使用ROLLUP或GROUPING SETS,它们提供了更细粒度的控制来生成特定的分组组合。同时,我们还可以使用HAVING子句来过滤不感兴趣的结果,比如去除包含NULL的...

    Oracle函数及其查询.pptx

    Oracle 函数及其查询 Oracle 函数是指在 Oracle 数据库中可以使用的一系列函数,包括单行函数、聚合函数、日期函数、类型转换函数等。这些函数可以在 SELECT ...* GROUPING SETS:对查询结果进行 grouping sets 操作

    Oracle聚合函数及其扩展使用

    Oracle 聚合函数及其扩展使用 Oracle 聚合函数是指在 Oracle 数据库中对数据进行汇总和计算的函数。这些函数可以对数据进行统计、分析和计算,得到有用的信息。 1. COUNT(*):COUNT(*) 函数用于计算查询结果中的...

    《Pro Oracle SQL》Chapter7 --7.6Eliminate NULLs with the GROUPING() Function

    这个函数通常与GROUPING SETS、CUBE或ROLLUP等高级分组技术结合使用,帮助用户更灵活地处理NULL值和其他分组情况。 例如,如果我们有一个包含产品信息的数据表,其中有些产品的供应商信息可能是NULL,我们可能想要...

    ORACLE学习笔记系列(15)使用扩展的 GROUP BY 子句

    在某些情况下,你可能需要同时使用WITH CUBE和WITH ROLLUP,这可以通过GROUPING SETS实现。你可以创建一个包含所有所需分组的集合,包括CUBE和ROLLUP的所有组合。 4. **GROUP_ID 函数**: Oracle特有的GROUP_ID...

    oracle 分组函数

    6. GROUPING SETS, CUBE, ROLLUP:这些是更高级的分组功能,可以生成多个分组组合,用于多维数据分析。 三、使用注意事项 1. 分组函数不能与非分组列一起出现在SELECT语句的非聚合表达式中,除非该列被包含在`...

    oracle分析函数介绍

    Rollup函数用于生成多级汇总数据,它可以创建一个类似于SQL GROUP BY语句的“GROUP BY GROUPING SETS”的效果。例如,可以计算每个区域、每个网络类型以及整个数据集的总费用。 Cube函数则更进一步,它不仅提供...

    Oracle 10g中的高级SQL函数

    `GROUP BY` 和 `HAVING` 子句是SQL中的基础工具,但在Oracle 10g中,你可以使用 `CUBE()`, `ROLLUP()`, `GROUPING SETS()` 进行多维度分析,创建更复杂的分组。`CONNECT BY` 用于构建层次结构,如组织结构或产品分类...

    oracle函数大全

    - `GROUP BY`和`ROLLUP`、`CUBE`、`GROUPING SETS`配合聚合函数实现分组汇总。 3. **分析函数**: - `RANK()`、`DENSE_RANK()`、`ROW_NUMBER()`用于排序和行编号。 - `LEAD()`、`LAG()`获取行的前后值,`FIRST_...

    oracle分区

    它用于区分标准的NULL值和由`ROLLUP`、`CUBE`或`GROUPING SETS`操作返回的NULL值。这些操作在多维数据分析中用于生成汇总数据,`GROUPING`函数可以帮助识别哪些NULL值代表整体的汇总,而非单个行的缺失值。例如,在...

    Oracle 10g培训经典_中文版

    - Les17_对 GROUP BY 子句的扩展.ppt可能深入讨论了GROUP BY的高级用法,如HAVING子句和ROLLUP/CUBE/GROUPING SETS。 通过这套培训资料,学习者可以从基础的SQL语法到复杂的数据库管理技巧逐步进阶,了解并掌握...

    sql-Group-by.rar_oracle

    8. **GROUPING SETS**: GROUPING SETS结合了ROLLUP和CUBE的功能,允许你指定一组特定的分组组合。 9. **DISTRIBUTE BY**: 虽然不是标准SQL的一部分,但某些Oracle版本支持DISTRIBUTE BY,它用于并行查询,帮助在多...

    oracle 11g SQL 课件

    7. 高级查询技巧:这包括联接操作(INNER JOIN, OUTER JOIN, SELF JOIN)、子查询、集合操作(UNION, INTERSECT, EXCEPT)、分组和聚合函数(GROUP BY, HAVING, ROLLUP, CUBE, GROUPING SETS)以及窗口函数。...

    不错的oracle教学课件

    10. **Les17分组查询扩展.ppt** - 分组查询的高级用法,可能包含GROUP BY ROLLUP、CUBE和GROUPING SETS,这些功能允许更灵活的数据汇总和分析。 通过这个教学课件,学习者不仅可以掌握Oracle SQL的基本语法,还能...

    Oracle常见用法

    4. **`GROUPING`函数**:`GROUPING`用于识别由`ROLLUP`、`CUBE`或`GROUPING SETS`返回的空值,区分标准空值和汇总情况。 **`HAVING`子句**: `HAVING`在`GROUP BY`后使用,用于筛选分组后的结果,可以包含聚合函数...

    Oracle杂记

    扩展的GROUP BY可能涉及多级分组、GROUPING SETS、CUBE和ROLLUP等高级功能,这些在处理复杂的数据汇总和分析时非常有用。 综上所述,Oracle数据库管理不仅涉及基础的SQL操作,还包括深入的性能优化和高级特性应用。...

    Oracle高级sql学习与练习

    10. 增强GROUP BY功能,使用GROUP BY扩展选项,如GROUPING SETS、CUBE和ROLLUP等,可以实现更复杂的聚合计算。 11. 分析函数(ANALYTICAL FUNCTIONS)是Oracle SQL的高级特性之一,允许在数据集上进行窗口计算,...

Global site tag (gtag.js) - Google Analytics