Enhancements to the GROUP BY Clause

1.带ROLLUP或CUBE操作的GROUP BY语句
•带ROLLUP或CUBE的GROUP BY子句,通过交叉引用列来产生超合计行
•ROLLUP分组产生一个包含常规分组行和小计值的结果集
•CUBE分组产生一个包含ROLLUP行和交叉表行的结果集

2.ROLLUP 操作
•语法:
 SELECT [列名 ... ] group_function(列名)...
 FROM 表名 [WHERE 子句]
 GROUP BY ROLLUP (列名 ... )
 [HAVING 子句] [ORDER BY 子句];

•ROLLUP 是一个 GROUP BY 子句的扩展,用 ROLLUP 操作产生小计和累计
 实际上,是先按group by子句进行分组,然后在分组的基础上进行横行小计和总计

•示例:
=============================================================================
SQL> SELECT department_id, job_id, SUM(salary)
  2  FROM employees
  3  WHERE department_id < 60
  4  GROUP BY ROLLUP(department_id, job_id);

DEPARTMENT_ID JOB_ID     SUM(SALARY)
------------- ---------- -----------
           10 AD_ASST           4400 -----(group1) regular rows
           10                   4400 ----------(group2) superaggregate rows(subtotals)
           20 MK_MAN           13000 -----(group1) regular rows
           20 MK_REP            6000 -----(group1) regular rows
           20                  19000 ----------(group2) superaggregate rows(subtotals)
           50 ST_MAN            5800 -----(group1) regular rows
           50 ST_CLERK         11700 -----(group1) regular rows
           50                  17500 ----------(group2) superaggregate rows(subtotals)
                               40900 ----------(group3) superaggregate rows
=============================================================================

•关于ROLLUP(列名 ... )的括号中的列名列表
 列名列表中各列的次序很重要,一般与select子句中的列名列表保持一致
 如果列名列表中有n个列,则查询结果的行可以分为 n+1 组(见上面的示例)
 基于列名列表中最后一个列的行称为regular rows(也就是上面示例的group1的行,基于job_id列)
 结果集的最后一行总是最后的合计值
 可以再参考下面的示例
 示例2:
=============================================================================
SQL> select department_id,job_id,manager_id,sum(salary)
  2  from employees where department_id < 60
  3  group by rollup(department_id,job_id,manager_id)
  4  order by 3,2,1;

DEPARTMENT_ID JOB_ID     MANAGER_ID SUM(SALARY)
------------- ---------- ---------- -----------
           20 MK_MAN            100       13000   --(group1) 基于列名列表中的第1、2、3列
           50 ST_MAN            100        5800   --(group1) 
           10 AD_ASST           101        4400   --(group1)
           50 ST_CLERK          124       11700   --(group1)
           20 MK_REP            201        6000   --(group1)
           10 AD_ASST                      4400   --(group2) 基于列名列表中的第1、2列
           20 MK_MAN                      13000   --(group2)
           20 MK_REP                       6000   --(group2)
           50 ST_CLERK                    11700   --(group2)
           50 ST_MAN                       5800   --(group2)
           10                              4400   --(group3) 基于列名列表中的第1列
           20                             19000   --(group3)
           50                             17500   --(group3)
                                          40900   --(group4) 总的合计值
=============================================================================

3.CUBE 操作
•语法:
 SELECT [列名 ... ] group_function(列名)...
 FROM 表名 [WHERE 子句]
 GROUP BY CUBE (列名 ... )
 [HAVING 子句] [ORDER BY 子句];

•CUBE 是一个 GROUP BY 子句的扩展,用CUBE操作能够产生带单个 SELECT 语句的交叉表值
 cube操作可以应用于所有的分组统计函数
 rollup操作只是生成部分分组的统计值,cube操作可以生成group by子句中全部列的所有分组的统计值

•rollup操作先按group by子句进行分组,然后在分组的基础上进行横行小计、纵向小计和总计
 在group by子句中列名列表的各列的每一种组合都能生成统计行,如果列名列表中有n个列的话,则会有2的n次方个组合,在数学上就是一个n维立方体(n-dimensional cube)

•示例:
=============================================================================
SQL> SELECT department_id, job_id, SUM(salary)
  2  FROM employees
  3  WHERE department_id < 60
  4  GROUP BY CUBE (department_id, job_id) ;

DEPARTMENT_ID JOB_ID     SUM(SALARY)
------------- ---------- -----------
                               40900  --(group4) 总的合计值
              MK_MAN           13000  -----(group3) 基于列名列表的第2列
              MK_REP            6000  -----(group3) 基于列名列表的第2列
              ST_MAN            5800  -----(group3) 基于列名列表的第2列
              AD_ASST           4400  -----(group3) 基于列名列表的第2列
              ST_CLERK         11700  -----(group3) 基于列名列表的第2列
           10                   4400  ----------(group2) 基于列名列表的第1列
           10 AD_ASST           4400  --(group1) 基于列名列表的第1、2列
           20                  19000  ----------(group2) 基于列名列表的第1列
           20 MK_MAN           13000  --(group1) 基于列名列表的第1、2列
           20 MK_REP            6000  --(group1) 基于列名列表的第1、2列
           50                  17500  ----------(group2) 基于列名列表的第1列
           50 ST_MAN            5800  --(group1) 基于列名列表的第1、2列
           50 ST_CLERK         11700  --(group1) 基于列名列表的第1、2列
=============================================================================
可以看到,cube操作实际上是对rollup的扩展,上面的示例与rollup的示例1相比,多了group3而已

4.GROUPING 函数
•语法:
 SELECT [列名...] ,group_function(列)... ,
     GROUPING(表达式1),GROUPING(表达式2)...
 FROM 表名 [WHERE 子句]
 GROUP BY ROLLUP|CUBE (列名 ... )
 [HAVING 子句] [ORDER BY 子句];

•当使用ROLLUP/CUBE操作计算统计值时,有时候有些列参与了统计,有些则没有参与统计
 grouping函数需要一个列名作为参数,如果该列参与了统计则返回0,如果没有参与统计则返回1
 group by子句的列名列表中有多少列,就必须有几个对应的grouping函数表达式

•示例:
=============================================================================
SQL> SELECT department_id DEPTID, job_id JOB,SUM(salary),
  2  GROUPING(department_id) GRP_DEPT, GROUPING(job_id) GRP_JOB
  3  FROM employees
  4  WHERE department_id < 50
  5  GROUP BY ROLLUP(department_id, job_id);

DEPTID JOB        SUM(SALARY)   GRP_DEPT    GRP_JOB
---------- ---------- ----------- ---------- ----------
        10 AD_ASST           4400          0          0
        10                   4400          0          1
        20 MK_MAN           13000          0          0
        20 MK_REP            6000          0          0
        20                  19000          0          1
                            23400          1          1
=============================================================================

5.分组集合(GROUPING SETS)
•GROUPING SETS 是 GROUP BY 子句更进一步的扩展
•你能够用 GROUPING SETS 在同一查询中定义多重分组
•Oracle计算在 GROUPING SETS 子句中指定的所有分组,然后组合各个个单独分组的结果
•分组集合的效率:
–对基表仅进行一个查询
–不需要写复杂的 UNION 语句
–GROUPING SETS 有更多的元素,更好的执行性能

•示例:
=============================================================================
SELECT department_id, job_id,manager_id,avg(salary)
FROM employees
GROUP BY GROUPING SETS
((department_id,job_id), (job_id,manager_id));
等效于
SELECT department_id, job_id,NULL,avg(salary)
 FROM employees
 GROUP BY department_id,job_id
UNION ALL
SELECT NULL,job_id,jmanager_id,avg(salary)
 FROM employees
 GROUP BY job_id,manager_id
=============================================================================

•CUBE/ROLLUP操作也可以用grouping set来实现
------------------------------------------------------------------------------------------
CUBE(a,b,c) 等效于 grouping set((a,b,c), (a,b), (a,c), (b,c), (a), (b), (c), ())
ROLLUP(a,b,c) 等效于 grouping set((a,b,c), (a,b), (a), ())
------------------------------------------------------------------------------------------

6.复合列(Composite Columns)
•复合列是一个作为整体被处理的列集合
 比如,ROLLUP (a,(b,c), d) ,其中 (b,c)是复合列

•为了指定复合列,GROUP BY 子句中在圆括号内的列可以进行分组(使用圆括号分组)
 Oracle在进行 ROLLUP 或 CUBE 操作时将复合列作为一个整体来处理

•一个复合列(Composite Columns)是一个列的集合,在分组计算的时候被视为一个整体
 可以在rollup、cube和grouping set中使用复合列

•当使用ROLLUP或CUBE时,复合列将某些分组被省略
 比如:ROLLUP(a, (b, c)) 等效于 grouping set((a,b,c),(a),()) ,没有了(a,b)

•示例:
=============================================================================
SQL> select department_id, job_id, manager_id, sum(salary)
  2  from employees where department_id < 60
  3  group by rollup(department_id,(job_id,manager_id));

DEPARTMENT_ID JOB_ID     MANAGER_ID SUM(SALARY)
------------- ---------- ---------- -----------
           10 AD_ASST           101        4400
           10                              4400
           20 MK_MAN            100       13000
           20 MK_REP            201        6000
           20                             19000
           50 ST_MAN            100        5800
           50 ST_CLERK          124       11700
           50                             17500
                                          40900
=============================================================================

7.连接分组(Concatenated Groupings)
•连接分组提供一种简明的方式来生成有用的分组组合
•为了指定连接分组集合,用逗号分开多重分组集合、ROLLUP和CUBE操作
 这样,Oracle可以方便地将它们组合在一个单个的GROUP BY子句中
•结果集是每个分组集的交叉分组
 比如:GROUP BY GROUPING SETS(a,b), GROUPING SETS(c,d) 等效 (a,c), (a,d), (b,c), (b,d)
 
•示例:
=============================================================================
SQL> select department_id, job_id, manager_id, sum(salary)
  2  from employees where department_id < 60
  3  group by department_id, rollup(job_id), cube(manager_id);

DEPARTMENT_ID JOB_ID     MANAGER_ID SUM(SALARY)
------------- ---------- ---------- -----------
           10 AD_ASST           101        4400
           20 MK_MAN            100       13000
           20 MK_REP            201        6000
           50 ST_MAN            100        5800
           50 ST_CLERK          124       11700   ---- (department_id, manager_id, job_id )
           10                   101        4400
           20                   100       13000
           20                   201        6000
           50                   100        5800
           50                   124       11700   ----- (department_id, manager_id)
           10 AD_ASST                      4400   ----- (department_id, job_id)
           10                              4400  
           20 MK_MAN                      13000   ----- (department_id, job_id)
           20 MK_REP                       6000   ----- (department_id, job_id)
           20                             19000  
           50 ST_MAN                       5800   ----- (department_id, job_id)
           50 ST_CLERK                    11700   ----- (department_id, job_id)
           50                             17500   ----- (department_id)
=============================================================================

转载于:https://www.cnblogs.com/zqf620/archive/2007/01/20/625560.html

lz0-007 读书笔记17相关推荐

  1. 进入保护模式(三)——《x86汇编语言:从实模式到保护模式》读书笔记17

    (十)保护模式下的栈 76 ;以下用简单的示例来帮助阐述32位保护模式下的堆栈操作 77 mov cx,00000000000_11_000B ;加载堆栈段选择子 78 mov ss,cx 79 mo ...

  2. .Net之美读书笔记17

    .Net垃圾回收 垃圾回收:指的是CLR对托管堆的垃圾内存进行回收,由CLR自动处理,这里简单说下垃圾回收的机制. 引用类型的内存分布 我们知道引用对象分配在托管堆上,我们新建一个Person对象来分 ...

  3. 读书笔记17 《靠谱》大石哲之

    先讲结论--在短时间内将必要的信息传递给对方 PREP模式: point 结论 reason 依据 example 具体事例 point 重申结论后结束 结论先行 不找借口,坦率回答"是&q ...

  4. 《构建之法》第4.17章读书笔记

    <构建之法>第4.17章读书笔记 第四章 原文语句: 异常不能跨过DLL或进程的边界来传递信息,所以异常不是万能的. 提出问题: 1.什么是DLL?DLL是来解决什么问题的? 网上说法: ...

  5. 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 21

    大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 211 第 ...

  6. 小啊呜产品读书笔记001:《邱岳的产品手记-09》第17讲 产品经理如何获得非权力性的影响力 第18讲 产品案例分析:WWFTogether的情怀设计

    小啊呜产品读书笔记001:<邱岳的产品手记-09>第17讲 产品经理如何获得非权力性的影响力 & 第18讲 产品案例分析:WWFTogether的情怀设计 一.今日阅读计划 二.泛 ...

  7. 【《C Primer Plus》读书笔记】第17章:高级数据表示

    [<C Primer Plus>读书笔记]第17章:高级数据表示 17.1 研究数据表示 17.2 从数组到链表 17.3 抽象数据类型(ADT) 17.4 队列ADT 17.5 用队列进 ...

  8. (读书笔记) 暗时间 (2016.12.17更)

    好几天没写了,继续~ 下一个chapter,作者关系如何有效专注学习进行进一步的讨论. 读研以来最大的感受就是每天有很多可以分心的事,安排的计划总是被各类杂事打乱. 作者总结道,要真正专注做一件事很难 ...

  9. 读书笔记-人月神话17

    有多少书,我读过:有多少事,我做过:记录下学习的点点滴滴,每一天. 回顾一下经典,记录一下悟点. 读书笔记-人月神话 - 另外一面

最新文章

  1. python yield与递归
  2. ASP.NET Web 表单
  3. cdh 安装_使用Cloudera的CDH部署Hadoop:第三步,安装管理平台和数据库
  4. Linux /dev目录详解和Linux系统各个目录的作用
  5. Android版CCLabelTTF在setstring时出现黑块
  6. Activity的四种启动模式和onNewIntent()
  7. was6 linux 卸载,重新安装was61
  8. 第四:Pytest框架之命令行参数(二)
  9. 2021第四届全国大学生IT技能大赛“传智杯”AK
  10. win7降低屏幕亮度_win7亮度调节不见了怎么办
  11. LaTeX完整例子_参考文献、图、表和公式
  12. css内容超过宽度显示省略号没效果,文字超过两行折叠省略
  13. 关于李沐深度学习softmax学习中代码出错的问题及解决方法
  14. 工欲善其事,必先利其器 - 修炼Android Studio操作技巧
  15. disallow php,在robots.txt中Disallow: /abc和Disallow: /abc/的区别
  16. Qt version is not properly installed,please run make install
  17. 平板触控笔要原装的吗?ipad电容笔推荐平价
  18. JZOJ 1307 Jail
  19. 动易安全开发手册[zt]
  20. layui点击表格图片放大

热门文章

  1. 散点图 横纵坐标_厉害了我的Python!散点图还能这么画
  2. Flyway 数据库脚本版本控制工具
  3. 集合覆盖模型例题_在打CodeForces的过程中发现的一个小模型
  4. Java基础---API概述---常用类(Object类/String类)---equals和==
  5. 「雕爷学编程」Arduino动手做(24)——水位传感器模块
  6. C#代码规范化(代码风格化)的几个函数
  7. struts2 url传参中文乱码
  8. 网站缓存技术总结( ehcache、memcache、redis对比)
  9. leetcode 203. Remove Linked List Elements(链表)
  10. 一次U3D DLL加密的记录(二)