您的位置:首页 > 数据库 > Oracle

Oracle分组ROLLUP、GROUP BY、GROUPING、GROUPING SETS区别和作用

2015-07-01 17:24 771 查看


Oracle分组ROLLUP、GROUP BY、GROUPING、GROUPING SETS区别和作用

1.ROLLUP
 

ROLLUP的作用相当于

SQL> set autotrace on

SQL> select department_id,job_id,count(*)

  2  from employees

  3  group by department_id,job_id

  4  union

  5  select department_id,null,count(*)

  6  from employees

  7  group by department_id

  8  union

  9  select null,null,count(*)

 10  from employees;



最后面的SA_REP表示此jobid没有部门,为null

这里的union系统默认进行了排序



使用ROLLUP能达到上面GROUP BY的功能,但性能开销更小

SQL> ed

已写入 file afiedt.buf

  1  select department_id,job_id,count(*)

  2  from employees

  3* group by rollup (department_id,job_id)

SQL> /



2.为什么ROLLUP会比GROUP BY性能好
ROLLUP(a,b,c)=a,b,c+a,b+a+All

通过一次全表扫描,得出a,b,c的分组统计信息后;分组统计a,b 相同,c不同的项即可得到a,b;依此类推……,就不用去多次全表扫描
 
3.ROLLUP的另类用法ROLLUP(a,(b,c))

ROLLUP((a,b))

SQL> ed

已写入 file afiedt.buf
  1  select department_id,job_id,count(*)

  2  from employees

  3* group by rollup ((department_id,job_id))

SQL> /
注意面的语句是group by rollup ((department_id,job_id))

不是group by rollup (department_id,job_id)





 
4.GROUPING函数的作用是放总记
如一个公司有多个部门,一个部门有多个岗位,一个岗位上有多个人

Rollup(部门,工作岗位)  sum(每人的工资)

当部门的GROUPING为0,工作岗位的GROUPING也为0时,说明是公司发的总工资,此时放公司总计

当部门的GROUPING为0,工作岗位的GROUPING也为1时,说明是部门发的总工资,此时放部门小记

当部门的GROUPING为1,工作岗位的GROUPING也为1时,显示的是某部门某职位的工资和计

SQL> SELECT   department_id DEPTID, job_id JOB,

  2           SUM(salary),

  3           GROUPING(department_id) GRP_DEPT,

  4           GROUPING(job_id) GRP_JOB

  5  FROM     employees

  6  GROUP BY ROLLUP(department_id, job_id);



第一个SA_REP表示此jobid没有部门,为null
 
5.GROUPING SETS与GROUPING的作用是不同的
 
Oracle服务器计算GROUPING SETS子句中所有的组并将结果通过UNION ALL组合成一个结果集.

GROUPING SETS的效果:1.只需要访问一次基表.2.不需要写很复杂的UNION语句.

SELECT   department_id, job_id, null manager_id,avg(salary)

FROM     employees

GROUP BY (department_id,job_id)

UNION ALL

SELECT   null department_id, job_id, manager_id,avg(salary)

FROM     employees

GROUP BY (job_id,manager_id)

等同于

SQL> set autotrace on

SQL> SELECT   department_id, job_id,

  2           manager_id,avg(salary)

  3  FROM     employees

  4  GROUP BY GROUPING SETS ((department_id,job_id), (job_id,manager_id));



上面得到的是通过job_id,manager_id分组的avg(salary)

下面的是通过department_id,job_id分组的avg(salary)





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: