Oralce 高级 sql 之 rollup 与 cube

在 oracle sql 查询中,oracle 提供了一些高级功能能够简化 sql 查询语句以及提高查询性能。下面将介绍 rollup,cube的用法与区别。

1. rollup

rollup 能够在 select 语句中计算指定分组字段的多个层次的小计以及合计. rollup 非常容易使用并且非常高效。

rollup 从右到左扫描分组字段, 逐步创建更高级别的小计. 最后再创建一行总计. rollup 将创建 n + 1 个层次(级别)的小计, n 指的是 rollup 中的字段数.

1.1 什么时候使用 rollup

  • 对于一些层次维度的小计(统计某些层次字段的小计及总计)
  • 对于数据仓库中的统计汇总表, rollup 能够简化统计汇总表并且提高查询统计汇总表的速度

1.2 rollup 例子

首先构造两个基本表 emp(员工表) 与 dept(部门表):

SQL> create table emp as select * from scott.emp;

Table created.

SQL> create table dept as select * from scott.dept;

Table created.

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
      7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

如果想统计每个部门每个职位的总薪水,sql 语句如下:

SQL> select b.dname, a.job, sum(a.sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by b.dname, a.job;

DNAME          JOB       SUM(A.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

9 rows selected.

如果想用一条 sql 语句统计每个部门每个职位的总薪水每个部门的总薪水以及所有部门的总薪水的话,势必要再用一个 group by 语句统计每个部门的总薪水然后再与上面的结果 union 起来才能得到最后的结果,但是这样写的话除了书写会复杂一点外,另外肯定还要多扫描几次 emp 与 dept 表,现在 oracle 提供了 rollup 子句,我们可以先来看看
rollup 子句的结果:

SQL> select b.dname, a.job, sum(a.sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by rollup(b.dname, a.job);

DNAME          JOB       SUM(A.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 子句会为每个部门增加一行小计以及为所有部门增加一行总计,即统计了每个部门的总薪水以及所有部门的总薪水。

通常来说,rollup 往往同 group by 语句一起使用,它是 group by 语句的一种扩展。

  • 如果语句为 group by rollup(a, b),oracle 将会从右到左先对字段 a 和 b 先进行 group by,然后对字段 A 进行 group by,最后对全表进行 group by。
  • 如果语句为 group by rollup(a, b, c), oracle 将从右到左先会对字段 a 和 b 和 c 先进行 group by, 然后对字段 a 和 b 进行 group by,然后对字段 a 进行 group by,最后对全表进行 group by。

下面我们将演示一个 rollup 三个字段的例子:

SQL> select b.dname, a.job, to_char(hiredate, 'yyyy'), sum(sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by b.dname, a.job, to_char(hiredate, 'yyyy')
  5  order by 1, 2, 3;

DNAME          JOB       TO_C   SUM(SAL)
-------------- --------- ---- ----------
ACCOUNTING     CLERK     1982       1300
ACCOUNTING     MANAGER   1981       2450
ACCOUNTING     PRESIDENT 1981       5000
RESEARCH       ANALYST   1981       3000
RESEARCH       ANALYST   1987       3000
RESEARCH       CLERK     1980        800
RESEARCH       CLERK     1987       1100
RESEARCH       MANAGER   1981       2975
SALES          CLERK     1981        950
SALES          MANAGER   1981       2850
SALES          SALESMAN  1981       5600

11 rows selected.

SQL> select b.dname, a.job, to_char(hiredate, 'yyyy'), sum(sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by rollup(b.dname, a.job, to_char(hiredate, 'yyyy'));

DNAME          JOB       TO_C   SUM(SAL)
-------------- --------- ---- ----------
SALES          CLERK     1981        950
SALES          CLERK                 950
SALES          MANAGER   1981       2850
SALES          MANAGER              2850
SALES          SALESMAN  1981       5600
SALES          SALESMAN             5600
SALES                               9400
RESEARCH       CLERK     1980        800
RESEARCH       CLERK     1987       1100
RESEARCH       CLERK                1900
RESEARCH       ANALYST   1981       3000
RESEARCH       ANALYST   1987       3000
RESEARCH       ANALYST              6000
RESEARCH       MANAGER   1981       2975
RESEARCH       MANAGER              2975
RESEARCH                           10875
ACCOUNTING     CLERK     1982       1300
ACCOUNTING     CLERK                1300
ACCOUNTING     MANAGER   1981       2450
ACCOUNTING     MANAGER              2450
ACCOUNTING     PRESIDENT 1981       5000
ACCOUNTING     PRESIDENT            5000
ACCOUNTING                          8750
                                   29025

24 rows selected.

1.3 部分 rollup(Partial rollup)

当你只想统计部分字段时, 可以使用部分 rollup. 例如, group by a, rollup(b, c), 这条语句将创建三个(2 + 1)级别的小计. 分别为级别 (a, b, c), 级别 (a, b) 以及级别 (a).

SQL> select b.dname, a.job, to_char(hiredate, 'yyyy'), sum(sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by b.dname, rollup(a.job, to_char(hiredate, 'yyyy'));

DNAME          JOB       TO_C   SUM(SAL)
-------------- --------- ---- ----------
SALES          CLERK     1981        950
SALES          CLERK                 950
SALES          MANAGER   1981       2850
SALES          MANAGER              2850
SALES          SALESMAN  1981       5600
SALES          SALESMAN             5600
SALES                               9400
RESEARCH       CLERK     1980        800
RESEARCH       CLERK     1987       1100
RESEARCH       CLERK                1900
RESEARCH       ANALYST   1981       3000
RESEARCH       ANALYST   1987       3000
RESEARCH       ANALYST              6000
RESEARCH       MANAGER   1981       2975
RESEARCH       MANAGER              2975
RESEARCH                           10875
ACCOUNTING     CLERK     1982       1300
ACCOUNTING     CLERK                1300
ACCOUNTING     MANAGER   1981       2450
ACCOUNTING     MANAGER              2450
ACCOUNTING     PRESIDENT 1981       5000
ACCOUNTING     PRESIDENT            5000
ACCOUNTING                          8750

23 rows selected.

从上面的结果中可以看出,部分 rollup 产生的结果:

  • 普通的汇总行是由 group by 产生而不是 rollup
  • 不会产生总计

2. cube

cube 可以为指定的列创建各种不同组合的小计. 如果指定的列的数量为 n, group by cube 将创建 2 * n 个层次的小计. cube 是一种比 rollup 更细粒度的分组统计语句。先看看 cube 语句的结果:

2.1 什么时候使用 cube

  • 当需求中有类似 cross-tabular report (交叉报表)时
  • 对于数据仓库中的统计汇总表, rollup 能够简化统计汇总表并且提高查询统计汇总表的速度

2.2 cube 例子

SQL> select b.dname, a.job, sum(a.sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by cube(b.dname, a.job);

DNAME          JOB       SUM(A.SAL)
-------------- --------- ----------
                              29025
               CLERK           4150
               ANALYST         6000
               MANAGER         8275
               SALESMAN        5600
               PRESIDENT       5000
SALES                          9400
SALES          CLERK            950
SALES          MANAGER         2850
SALES          SALESMAN        5600
RESEARCH                      10875
RESEARCH       CLERK           1900
RESEARCH       ANALYST         6000
RESEARCH       MANAGER         2975
ACCOUNTING                     8750
ACCOUNTING     CLERK           1300
ACCOUNTING     MANAGER         2450
ACCOUNTING     PRESIDENT       5000

18 rows selected.

从上面的结果可以看出,group by cube(b.dname, a.job) 语句首先统计所有部门的总薪水,然后统计每个职位(a.job)的总薪水,然后统计每个部门(b.dname)的总薪水,最后统计每个部门每个职位(b.dname, a.job)的总薪水。

  • 如果语句为 group by cube(a, b),oracle 首先对字段 a 和 b 进行 group by,然后对字段 a 进行 group by,然后对字段 b 进行 group by,最后对全表进行 group by。
  • 如果语句为 group by cube(a, b, c),oracle 进行分组的字段分别为 (a, b, c),(a, b),(a, c),(b, c),(a),(b),(c),最后对全表的总计

下面演示 cube 三个字段的例子:

SQL> select b.dname, a.job, to_char(hiredate, 'yyyy'), sum(sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by cube(b.dname, a.job, to_char(hiredate, 'yyyy'));

DNAME          JOB       TO_C   SUM(SAL)
-------------- --------- ---- ----------
                                   29025
                         1980        800
                         1981      22825
                         1982       1300
                         1987       4100
               CLERK                4150
               CLERK     1980        800
               CLERK     1981        950
               CLERK     1982       1300
               CLERK     1987       1100
               ANALYST              6000
               ANALYST   1981       3000
               ANALYST   1987       3000
               MANAGER              8275
               MANAGER   1981       8275
               SALESMAN             5600
               SALESMAN  1981       5600
               PRESIDENT            5000
               PRESIDENT 1981       5000
SALES                               9400
SALES                    1981       9400
SALES          CLERK                 950
SALES          CLERK     1981        950
SALES          MANAGER              2850
SALES          MANAGER   1981       2850
SALES          SALESMAN             5600
SALES          SALESMAN  1981       5600
RESEARCH                           10875
RESEARCH                 1980        800
RESEARCH                 1981       5975
RESEARCH                 1987       4100
RESEARCH       CLERK                1900
RESEARCH       CLERK     1980        800
RESEARCH       CLERK     1987       1100
RESEARCH       ANALYST              6000
RESEARCH       ANALYST   1981       3000
RESEARCH       ANALYST   1987       3000
RESEARCH       MANAGER              2975
RESEARCH       MANAGER   1981       2975
ACCOUNTING                          8750
ACCOUNTING               1981       7450
ACCOUNTING               1982       1300
ACCOUNTING     CLERK                1300
ACCOUNTING     CLERK     1982       1300
ACCOUNTING     MANAGER              2450
ACCOUNTING     MANAGER   1981       2450
ACCOUNTING     PRESIDENT            5000
ACCOUNTING     PRESIDENT 1981       5000

48 rows selected.

2.3 部分 cube (partial cube)

部分 cube 类似于部分 rollup, 把列放在 cube 操作符的外面能够限制生成列组合的小计. 例如, group by a, cube(b, c), 这条语句将产生 4 (2 * 2) 个层次的小计, 分别为层次 (a, b, c), 层次 (a, b), 层次 (a, c), 层次 (a).

SQL> select b.dname, a.job, to_char(hiredate, 'yyyy'), sum(sal)
  2  from emp a, dept b
  3  where a.deptno = b.deptno
  4  group by b.dname, cube(a.job, to_char(hiredate, 'yyyy'));

DNAME          JOB       TO_C   SUM(SAL)
-------------- --------- ---- ----------
SALES                               9400
SALES                    1981       9400
SALES          CLERK                 950
SALES          CLERK     1981        950
SALES          MANAGER              2850
SALES          MANAGER   1981       2850
SALES          SALESMAN             5600
SALES          SALESMAN  1981       5600
RESEARCH                           10875
RESEARCH                 1980        800
RESEARCH                 1981       5975
RESEARCH                 1987       4100
RESEARCH       CLERK                1900
RESEARCH       CLERK     1980        800
RESEARCH       CLERK     1987       1100
RESEARCH       ANALYST              6000
RESEARCH       ANALYST   1981       3000
RESEARCH       ANALYST   1987       3000
RESEARCH       MANAGER              2975
RESEARCH       MANAGER   1981       2975
ACCOUNTING                          8750
ACCOUNTING               1981       7450
ACCOUNTING               1982       1300
ACCOUNTING     CLERK                1300
ACCOUNTING     CLERK     1982       1300
ACCOUNTING     MANAGER              2450
ACCOUNTING     MANAGER   1981       2450
ACCOUNTING     PRESIDENT            5000
ACCOUNTING     PRESIDENT 1981       5000

29 rows selected.
时间: 2024-10-11 02:31:38

Oralce 高级 sql 之 rollup 与 cube的相关文章

[转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)

原文地址:http://blog.csdn.net/u014558001/article/details/42387929 本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用法,这些函数可以理解为GroupBy分组函数封装后的精简用法,相当于多个union all 的组合显示效果,但是要比 多个union all的效率要高. 其实这些函数在时间的程序开发中应用的并不多,至少在我工作的多年时间中没用过几次,因为现在的各种开发工具/平台都自带了这些高级分组统计功能,使用的方

SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

原文:SQL Server 之 GROUP BY.GROUPING SETS.ROLLUP.CUBE 1.创建表 Staff CREATE TABLE [dbo].[Staff]( [ID] [int] IDENTITY(1,1) NOT NULL, [Name] [varchar](50) NULL, [Sex] [varchar](50) NULL, [Department] [varchar](50) NULL, [Money] [int] NULL, [CreateDate] [date

SQL Server ->> GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID

在我们制作报表的时候常常需要分组聚合.多组聚合和总合.如果通过另外的T-SQL语句来聚合难免性能太差.如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生成整个结果集然后再聚合,而且最最重要的时很多情况下报表的聚合功能可能没办法达到我们需要的效果.GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID这几个聚合函数的作用就是在原始语句的基础上完成很多像财务报表需要的聚合功能. GROUPING SETS相

转:GROUPING SETS、ROLLUP、CUBE

转:http://blog.csdn.net/shangboerds/article/details/5193211 大家对GROUP BY应该比较熟悉,如果你感觉自己并不完全理解GROUP BY,那么本文不适合你.还记得当初学习SQL的时候,总是理解不了GROUP BY的作用,经过好长时间才终于明白GROUP BY的真谛.当然,这和我本人笨也有关系,但是GROUP BY的确不好理解.本文将介绍DB2 GROUPING SETS.ROLLUP.CUBE的使用方法,这些关键字比GROUP BY更难

第9章 高级 SQL Server 配置

第9章  高级 SQL Server 配置 9.1  使用sp_config 9.1.1  执行查询 9.1.2  配置基本参数 9.1.3  配置高级参数 9.2  管理员专用连接 9.3  使用SQLCMD

50句高级SQL语句

一个题目涉及到的50个Sql语句 --(下面表的结构以给出,自己在数据库中建立表.并且添加相应的数据,数据要全面些. 其中Student表中,SId为学生的ID) ------------------------------------表结构----------------------------------------学生表tblStudent(编号StuId.姓名StuName.年龄StuAge.性别StuSex)--课程表tblCourse(课程编号CourseId.课程名称CourseN

GROUP BY ROLLUP和CUBE 用法

ROLLUP和CUBE 用法           Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是Group by  ROLLUP(A, B, C)的话,首先会对(A.B.C)进行GROUP BY,然后对(A.B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作. 如果是GROUP BY CUBE(A, B, C),则首先会对(A.B.C)进行GROUP BY,然后依次是(A.B),(A.C),(A),(B

Oracle中group by 的扩展函数rollup、cube、grouping sets

Oracle的group by除了基本用法以外,还有3种扩展用法,分别是rollup.cube.grouping sets,分别介绍如下: 1.rollup 对数据库表emp,假设其中两个字段名为a,b,c. 如果使用group by rollup(a,b),首先会对(a,b)进行group by ,然后对 a 进行 group by ,最后对全表进行 group by 操作. 如下查询结果: 查询语句 Select deptno,job,sum(sal) from emp group by r

SQLServer应用程序的高级Sql注入

[概 要] 这篇文章讨论常用的"sql注入"技术的细节,应用于流行的Ms IIS/ASP/SQL-Server平台.这里探讨有关这种攻击各种可以注入程序访问数据和数据库防范的方法.这篇文章面向两种读者:一是基于数据库web程序开发人员和审核各种web程序的安全专家. [介 绍] 结构化查询语言(SQL)是一种用来和数据库交 互的文本语言SQL语言多种多样,大多的方言版本都共同宽松地遵循SQL-92标准(最新的ANSI标准[译者注:目前最新的是SQL-99]).SQL 运行的典型的操作是