【ROLLUP】Oracle分组函数之高效的ROLLUP

㈠ 初始化实验坏境

 

hr@ORCL> create table rollup_test as
  2      select e.department_id,j.job_title,e.first_name,e.salary
  3        from employees e,jobs j
  4       where e.job_id=j.job_id;

Table created.

hr@ORCL> select * from rollup_test;

DEPARTMENT_ID JOB_TITLE                           FIRST_NAME               SALARY
------------- ----------------------------------- -------------------- ----------
           50 Shipping Clerk                      Donald                     2600
           50 Shipping Clerk                      Douglas                    2600
           10 Administration Assistant            Jennifer                   4400
           20 Marketing Manager                   Michael                   13000
           20 Marketing Representative            Pat                        6000
           40 Human Resources Representative      Susan                      6500
           70 Public Relations Representative     Hermann                   10000
          110 Accounting Manager                  Shelley                   12000
          110 Public Accountant                   William                    8300
           90 President                           Steven                    24000
           90 Administration Vice President       Neena                     17000
           90 Administration Vice President       Lex                       17000
           60 Programmer                          Alexander                  9000
           60 Programmer                          Bruce                      6000
           60 Programmer                          David                      4800
           60 Programmer                          Valli                      4800
           60 Programmer                          Diana                      4200
          100 Finance Manager                     Nancy                     12000
          100 Accountant                          Daniel                     9000
          100 Accountant                          John                       8200
          100 Accountant                          Ismael                     7700
          100 Accountant                          Jose Manuel                7800
          100 Accountant                          Luis                       6900
           30 Purchasing Manager                  Den                       11000
           30 Purchasing Clerk                    Alexander                  3100
           30 Purchasing Clerk                    Shelli                     2900
           30 Purchasing Clerk                    Sigal                      2800
           30 Purchasing Clerk                    Guy                        2600
           30 Purchasing Clerk                    Karen                      2500
           50 Stock Manager                       Matthew                    8000
           ...............................................
           ...............................................
           ...............................................


 

㈡ 先看一下普通分组的效果:对DEPARTMENT_ID进行普通的GROUP BY操作---按照小组进行分组

 

hr@ORCL> select department_id,sum(salary) from rollup_test group by department_id;

DEPARTMENT_ID SUM(SALARY)
------------- -----------
          100       51600
           30       24900
                     7000
           20       19000
           70       10000
           90       58000
          110       20300
           50      156400
           40        6500
           80      304500
           10        4400
           60       28800

12 rows selected.


 

㈢ 对DEPARTMENT_ID进行普通的ROLLUP操作---按照小组进行分组,同时求总计

 

hr@ORCL> select department_id,sum(salary) from rollup_test group by rollup(department_id);

DEPARTMENT_ID SUM(SALARY)
------------- -----------
           10        4400
           20       19000
           30       24900
           40        6500
           50      156400
           60       28800
           70       10000
           80      304500
           90       58000
          100       51600
          110       20300
                     7000
                   691400

13 rows selected.

Elapsed: 00:00:00.06

Execution Plan
----------------------------------------------------------
Plan hash value: 3210238927

------------------------------------------------------------------------------------
| Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   107 |  2782 |     4  (25)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|             |   107 |  2782 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS FULL  | ROLLUP_TEST |   107 |  2782 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        648  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed


 

 

㈣ 使用Group By语句翻译一下上面的SQL语句如下(union all一个统计所有数据的行)

 

hr@ORCL> select department_id,sum(salary) from rollup_test group by department_id
  2      union all
  3      select null, sum(salary) from rollup_test
  4      order by 1;

DEPARTMENT_ID SUM(SALARY)
------------- -----------
           10        4400
           20       19000
           30       24900
           40        6500
           50      156400
           60       28800
           70       10000
           80      304500
           90       58000
          100       51600
          110       20300
                     7000
                   691400

13 rows selected.


Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 1519347417

------------------------------------------------------------------------------------
| Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   108 |  2795 |     8  (25)| 00:00:01 |
|   1 |  SORT ORDER BY       |             |   108 |  2795 |     7  (58)| 00:00:01 |
|   2 |   UNION-ALL          |             |       |       |            |          |
|   3 |    HASH GROUP BY     |             |   107 |  2782 |     4  (25)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| ROLLUP_TEST |   107 |  2782 |     3   (0)| 00:00:01 |
|   5 |    SORT AGGREGATE    |             |     1 |    13 |            |          |
|   6 |     TABLE ACCESS FULL| ROLLUP_TEST |   107 |  1391 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
        648  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed


 

㈤ 再看一个ROLLUP两列的情况

 

hr@ORCL> select department_id,job_title,sum(salary) from rollup_test group by rollup(department_id,job_title);

DEPARTMENT_ID JOB_TITLE                           SUM(SALARY)
------------- ----------------------------------- -----------
              Sales Representative                       7000
                                                         7000
           10 Administration Assistant                   4400
           10                                            4400
           20 Marketing Manager                         13000
           20 Marketing Representative                   6000
           20                                           19000
           30 Purchasing Clerk                          13900
           30 Purchasing Manager                        11000
           30                                           24900
           40 Human Resources Representative             6500
           40                                            6500
           50 Stock Clerk                               55700
           50 Stock Manager                             36400
           50 Shipping Clerk                            64300
           50                                          156400
           60 Programmer                                28800
           60                                           28800
           70 Public Relations Representative           10000
           70                                           10000
           80 Sales Manager                             61000
           80 Sales Representative                     243500
           80                                          304500
           90 President                                 24000
           90 Administration Vice President             34000
           90                                           58000
          100 Accountant                                39600
          100 Finance Manager                           12000
          100                                           51600
          110 Public Accountant                          8300
          110 Accounting Manager                        12000
          110                                           20300
                                                       691400

33 rows selected.

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 3210238927

------------------------------------------------------------------------------------
| Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   107 |  4815 |     4  (25)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|             |   107 |  4815 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS FULL  | ROLLUP_TEST |   107 |  4815 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
       1511  bytes sent via SQL*Net to client
        407  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         33  rows processed


 

㈥ 上面的SQL语句该如何使用Group By进行翻译呢?

 

hr@ORCL> select department_id,job_title,sum(salary) from rollup_test group by department_id,job_title
  2      union all
  3      select department_id,null,sum(salary) from rollup_test group by department_id
  4      union all
  5      select null,null,sum(salary) from rollup_test
  6      order by 1,2;


DEPARTMENT_ID JOB_TITLE                           SUM(SALARY)
------------- ----------------------------------- -----------
           10 Administration Assistant                   4400
           10                                            4400
           20 Marketing Manager                         13000
           20 Marketing Representative                   6000
           20                                           19000
           30 Purchasing Clerk                          13900
           30 Purchasing Manager                        11000
           30                                           24900
           40 Human Resources Representative             6500
           40                                            6500
           50 Shipping Clerk                            64300
           50 Stock Clerk                               55700
           50 Stock Manager                             36400
           50                                          156400
           60 Programmer                                28800
           60                                           28800
           70 Public Relations Representative           10000
           70                                           10000
           80 Sales Manager                             61000
           80 Sales Representative                     243500
           80                                          304500
           90 Administration Vice President             34000
           90 President                                 24000
           90                                           58000
          100 Accountant                                39600
          100 Finance Manager                           12000
          100                                           51600
          110 Accounting Manager                        12000
          110 Public Accountant                          8300
          110                                           20300
              Sales Representative                       7000
                                                       691400
                                                         7000

33 rows selected.

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 2979879831

------------------------------------------------------------------------------------
| Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   215 |  7610 |    12  (25)| 00:00:01 |
|   1 |  SORT ORDER BY       |             |   215 |  7610 |    11  (73)| 00:00:01 |
|   2 |   UNION-ALL          |             |       |       |            |          |
|   3 |    HASH GROUP BY     |             |   107 |  4815 |     4  (25)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| ROLLUP_TEST |   107 |  4815 |     3   (0)| 00:00:01 |
|   5 |    HASH GROUP BY     |             |   107 |  2782 |     4  (25)| 00:00:01 |
|   6 |     TABLE ACCESS FULL| ROLLUP_TEST |   107 |  2782 |     3   (0)| 00:00:01 |
|   7 |    SORT AGGREGATE    |             |     1 |    13 |            |          |
|   8 |     TABLE ACCESS FULL| ROLLUP_TEST |   107 |  1391 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          9  consistent gets
          0  physical reads
          0  redo size
       1513  bytes sent via SQL*Net to client
        407  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         33  rows processed


 

㈦ 补充一步,体验一下GROUPING函数的效果

 

SQL> select department_id,job_title,grouping(department_id),grouping(job_title),sum(salary)
  2  from rollup_test group by rollup(department_id,job_title);
 
DEPARTMENT_ID JOB_TITLE                           GROUPING(DEPARTMENT_ID) GROUPING(JOB_TITLE) SUM(SALARY)
------------- ----------------------------------- ----------------------- ------------------- -----------
              Sales Representative                                      0                   0        7000
                                                                        0                   1        7000
           10 Administration Assistant                                  0                   0        4400
           10                                                           0                   1        4400
           20 Marketing Manager                                         0                   0       13000
           20 Marketing Representative                                  0                   0        6000
           20                                                           0                   1       19000
           30 Purchasing Clerk                                          0                   0       13900
           30 Purchasing Manager                                        0                   0       11000
           30                                                           0                   1       24900
           40 Human Resources Representative                            0                   0        6500
           40                                                           0                   1        6500
           50 Stock Clerk                                               0                   0       55700
           50 Stock Manager                                             0                   0       36400
           50 Shipping Clerk                                            0                   0       64300
           50                                                           0                   1      156400
           60 Programmer                                                0                   0       28800
           60                                                           0                   1       28800
           70 Public Relations Representative                           0                   0       10000
           70                                                           0                   1       10000
           80 Sales Manager                                             0                   0       61000
           80 Sales Representative                                      0                   0      243500
           80                                                           0                   1      304500
           90 President                                                 0                   0       24000
           90 Administration Vice President                             0                   0       34000
           90                                                           0                   1       58000
          100 Accountant                                                0                   0       39600
          100 Finance Manager                                           0                   0       12000
          100                                                           0                   1       51600
          110 Public Accountant                                         0                   0        8300
          110 Accounting Manager                                        0                   0       12000
          110                                                           0                   1       20300
                                                                        1                   1      691400
 
33 rows selected


       看出来什么效果了么?
       如果显示“1”表示GROUPING函数对应的列(例如JOB_TITLE字段)是由于ROLLUP函数所产生的空值对应的信息
           即对此列进行汇总计算后的结果
       如果显示“0”表示此行对应的这列参未与ROLLUP函数分组汇总活动
      
       GROUPING函数可以接受一列,返回0或者1
       如果列值为空,那么GROUPING()返回1;如果列值非空,那么返回0
       GROUPING只能在使用ROLLUP或CUBE的查询中使用
       当需要在返回空值的地方显示某个值时,GROUPING()就非常有用

 

㈧ 小结


   ROLLUP在数据统计和报表生成过程中带来极大的便利,而且效率比起来Group By + Union组合方法效率高得多
   这也体现了Oracle在SQL统计分析上人性化、自动化、高效率的特点

你可能感兴趣的:(【ROLLUP】Oracle分组函数之高效的ROLLUP)