rolllup巧用
--构造环境
drop table dept purge;
drop table emp purge;
create table dept as select * from scott.dept;
create table emp as select * from scott.emp;
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
set term off
set heading on
set verify off
set feedback off
set linesize 2000
set pagesize 30000
set long 999999999
set longchunksize 999999
set autotrace off
---写法1
SELECT a.dname,b.job,SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY a.dname,b.job;
DNAME JOB SUM_SAL
-------------- --------- ----------
SALES MANAGER 2850
SALES CLERK 950
ACCOUNTING MANAGER 2450
ACCOUNTING PRESIDENT 5000
ACCOUNTING CLERK 1300
SALES SALESMAN 5600
RESEARCH MANAGER 2975
RESEARCH ANALYST 6000
RESEARCH CLERK 1900
/*
不错不错,自我陶醉中....
停!先别得意,有人跑来说希望能增加一列总的汇总。
等等,更变态的需求来了,希望能得到不同DNAME的各自汇总!
*/
---写法2(没办法,先想到如下一个办法来实现楼上的变态需求)
set autotrace on
select * from (
SELECT a.dname,b.job,SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY a.dname,b.job
UNION ALL
--实现了部门的小计
SELECT a.dname,NULL, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY a.dname
UNION ALL
--实现了所有部门总的合计
SELECT NULL,NULL, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno)
order by dname;
DNAME JOB SUM_SAL
-------------- --------- ----------
ACCOUNTING CLERK 1300
ACCOUNTING MANAGER 2450
ACCOUNTING PRESIDENT 5000
ACCOUNTING 8750
RESEARCH CLERK 1900
RESEARCH MANAGER 2975
RESEARCH ANALYST 6000
RESEARCH 10875
SALES CLERK 950
SALES MANAGER 2850
SALES SALESMAN 5600
SALES 9400
29025
union all 合并笨办法产生的执行计划
-------------------------------------------------------------------------------
Plan hash value: 2979078843
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 29 | 812 | 23 (22)| 00:00:01 |
| 1 | SORT ORDER BY | | 29 | 812 | 23 (22)| 00:00:01 |
| 2 | VIEW | | 29 | 812 | 22 (19)| 00:00:01 |
| 3 | UNION-ALL | | | | | |
| 4 | HASH GROUP BY | | 14 | 756 | 8 (25)| 00:00:01 |
|* 5 | HASH JOIN | | 14 | 756 | 7 (15)| 00:00:01 |
| 6 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 7 | TABLE ACCESS FULL| EMP | 14 | 448 | 3 (0)| 00:00:01 |
| 8 | HASH GROUP BY | | 14 | 672 | 8 (25)| 00:00:01 |
|* 9 | HASH JOIN | | 14 | 672 | 7 (15)| 00:00:01 |
| 10 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL| EMP | 14 | 364 | 3 (0)| 00:00:01 |
| 12 | SORT AGGREGATE | | 1 | 39 | | |
|* 13 | HASH JOIN | | 14 | 546 | 7 (15)| 00:00:01 |
| 14 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
| 15 | TABLE ACCESS FULL| EMP | 14 | 364 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."DEPTNO"="B"."DEPTNO")
9 - access("A"."DEPTNO"="B"."DEPTNO")
13 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
18 consistent gets
0 physical reads
0 redo size
783 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
13 rows processed
---写法3(学本领很重要,如果你会rollup神功,性能就能大幅度提升,SQL书写也不麻烦了)
set autotrace on
SELECT a.dname,b.job, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY ROLLUP(a.dname,b.job);
DNAME JOB SUM_SAL
-------------- --------- ----------
SALES CLERK 950
SALES MANAGER 2850
SALES SALESMAN 5600
SALES 9400
RESEARCH CLERK 1900
RESEARCH ANALYST 6000
RESEARCH MANAGER 2975
RESEARCH 10875
ACCOUNTING CLERK 1300
ACCOUNTING MANAGER 2450
ACCOUNTING PRESIDENT 5000
ACCOUNTING 8750
29025
rollup写法产生的执行计划
-----------------------------------------------------------------------------
Plan hash value: 1037965942
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 756 | 8 (25)| 00:00:01 |
| 1 | SORT GROUP BY ROLLUP| | 14 | 756 | 8 (25)| 00:00:01 |
|* 2 | HASH JOIN | | 14 | 756 | 7 (15)| 00:00:01 |
| 3 | TABLE ACCESS FULL | DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | EMP | 14 | 448 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
6 consistent gets
0 physical reads
0 redo size
778 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
13 rows processed
--在这里应该可以清楚的发现,表的访问次数比union all硬平畴的要少,而且COST和逻辑读也少的多!
---写法4(如果你想再多一个维度,比如再增加雇佣年份的统计,之前union all硬拼凑的方法要崩溃了吧,不过rollup轻松搞定,如下)
SELECT to_char(b.hiredate,'yyyy') hire_year,a.dname,b.job, SUM(sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY ROLLUP(to_char(b.hiredate,'yyyy'),a.dname,b.job);
HIRE DNAME JOB SUM_SAL
---- -------------- --------- ----------
1980 RESEARCH CLERK 800
1980 RESEARCH 800
1980 800
1981 SALES CLERK 950
1981 SALES MANAGER 2850
1981 SALES SALESMAN 5600
1981 SALES 9400
1981 RESEARCH ANALYST 3000
1981 RESEARCH MANAGER 2975
1981 RESEARCH 5975
1981 ACCOUNTING MANAGER 2450
1981 ACCOUNTING PRESIDENT 5000
1981 ACCOUNTING 7450
1981 22825
1982 ACCOUNTING CLERK 1300
1982 ACCOUNTING 1300
1982 1300
1987 RESEARCH CLERK 1100
1987 RESEARCH ANALYST 3000
1987 RESEARCH 4100
1987 4100
29025
执行计划
----------------------------------------------------------------------------
Plan hash value: 1037965942
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 882 | 8 (25)| 00:00:01 |
| 1 | SORT GROUP BY ROLLUP| | 14 | 882 | 8 (25)| 00:00:01 |
|* 2 | HASH JOIN | | 14 | 882 | 7 (15)| 00:00:01 |
| 3 | TABLE ACCESS FULL | DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | EMP | 14 | 574 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
6 consistent gets
0 physical reads
0 redo size
1107 bytes sent via SQL*Net to client
427 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
22 rows processed
--看官们注意到了吗,多了一个维度的统计,无论是COST还是逻辑读,都没有增加,够帅!
---写法5 (另外,不止是增加维度,更换维度的次序,对rollup 也是轻而易举的事,如下)
SELECT b.job,a.dname, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY ROLLUP(b.job,a.dname);
JOB DNAME SUM_SAL
--------- -------------- ----------
CLERK SALES 950
CLERK RESEARCH 1900
CLERK ACCOUNTING 1300
CLERK 4150
ANALYST RESEARCH 6000
ANALYST 6000
MANAGER SALES 2850
MANAGER RESEARCH 2975
MANAGER ACCOUNTING 2450
MANAGER 8275
SALESMAN SALES 5600
SALESMAN 5600
PRESIDENT ACCOUNTING 5000
PRESIDENT 5000
29025
--------------------- 部分ROLLUP分组---------------------------------------
SELECT to_char(b.hiredate,'yyyy') hire_year,a.dname,b.job, SUM(sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP BY to_char(b.hiredate,'yyyy'),a.dname,ROLLUP(b.job);
rolllup巧用的更多相关文章
- [MySQL性能优化系列]巧用索引
1. 普通青年的索引使用方式 假设我们有一个用户表 tb_user,内容如下: name age sex jack 22 男 rose 21 女 tom 20 男 ... ... ... 执行SQL语 ...
- [ACM训练] ACM中巧用文件的输入输出来改写acm程序的输入输出 + ACM中八大输入输出格式
ACM中巧用文件的输入输出来改写acm程序的输入输出 经常有见大神们使用文件来代替ACM程序中的IO,尤其是当程序IO比较复杂时,可以使自己能够更专注于代码的测试,而不是怎样敲输入. C/C++代码中 ...
- TSql 巧用Alt 键
1,查看表的信息 在TSql 编辑器中,选中一个表,如图 点击Alt+F1,就可以查看表的属性定义 2,使用alt批量插入逗号 在Tsql中使用 in 子句,在(value_List)列表中,经常有很 ...
- 前端工程师技能之photoshop巧用系列第三篇——切图篇
× 目录 [1]切图信息 [2]切图步骤 [3]实战 前面的话 前端工程师除了使用photoshop进行测量之外,更重要的是要使用该软件进行切图.本文是photoshop巧用系列的第三篇——切图篇 切 ...
- 前端工程师技能之photoshop巧用系列第二篇——测量篇
× 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...
- 前端工程师技能之photoshop巧用系列第一篇——准备篇
× 目录 [1]作用 [2]初始化 [3]常用工具[4]快捷键 前面的话 photoshop是前端工程师无法回避的一个软件,这个软件本身很强大,但我们仅仅需要通过这个工具来完成基本的切图工作即可.本文 ...
- 巧用CSS实现分隔线
下面是几种简单实现分隔线的方法,个人比较喜欢第二种,我也给出了最后第五种比较2的写法,请大家拍砖,或者提供其他好的方法. 单个标签实现分隔线: 点此查看实例展示 .demo_line_01{ padd ...
- iOS开发之巧用Block和代理方法结合来传值
好久没写技术博客了,因为996的工作周期已经持续好几个月了.每天晚上回家都没有太多精力学习很多其他的东西,而且很多时候是接着完善工作的项目的模块开发.所以博客停歇了这么久,更新率也低了不少,今天补充一 ...
- jquery 巧用json传参
JavaScript代码,巧用JSON传参数function AddComment(content) { var comment = {}; comment.threadId = $("#s ...
随机推荐
- 怎么高效查找和正确改变谷歌浏览器编码格式(新版和旧版Google Chrome)(图文详解)
前言 今天,无意中在解决一个乱码问题,后台是有过判断解决兼容性问题,但是有个别电脑还是有乱码问题,就去想改变下前台的编码格式,突然发现一向好用的谷歌,居然找不到编码格式了! 上网百度了半天,查阅各种网 ...
- 【CSS】 布局之多列等高
这两天看了不少文章,对于css布局多了一些理解,现在来总结下. 我们来写一个最普遍的Top.Left.Content.Right.Foot布局. 第一步:自然是写一个坯子 <!DOCTYPE H ...
- 【ExtJS】一些基本概念的梳理
学习ExtJS有一段时间了,一些相关知识点虽然每天都在用,不过如果猛的一问起来还是会一愣,趁现在好好梳理下吧.长期修改添加,弄清楚什么就加入什么. 1.Ext.onReady(): onReady() ...
- orcale 之 pl/sql
基本结构 不多说直接来看下它的结构: DECLARE -- 此处声明一些变量.常量.或者用户自定的数据类型 -- 这一部分是可选的,如果不需要可以不写 BEGIN -- 程序的主体,这里可以写一些合法 ...
- unity2018的坑点
发布后有的电脑无法运行exe程序(反正我的电脑不行) 删除发布出来的一个叫UnityCrashHandler64.exe即可运行
- JavaScript数组forEach循环
JavaScript数组forEach循环 今天写JavaScript代码把forEach循环数组忘记写法了,在此记录一下以防止未来忘记. let a = [1, 2, 3]; a.forEach(f ...
- Java动态代理的理解
代码内容: https://github.com/cjy513203427/Java_Advanced_Knowledge/tree/master/src/com/advance/dynamic_pr ...
- 面向对象 OOP中的抽象类,接口以及多态
[抽象类与抽象方法] 1.什么是抽象方法? 没有方法体{}的方法,必须使用abstract关键字修饰,这样的方法,我们称之为抽象方法. abstract function say() 2.什么是抽象类 ...
- asfda
从事前端的朋友应该对"字体图标"这个词汇不陌生,为了适应越来越挑剔的屏幕,网页图标和简单图案使用.png来搭建已经基本上被淘汰了.取而代之的是使用css3和svg来绘制,而对于网页 ...
- 在线课程笔记—.NET基础
关于学习北京理工大学金旭亮老师在线课程的笔记. 介绍: 在线课程网址:http://mooc.study.163.com/university/BIT#/c 老师个人网站:http://jinxuli ...