一.GROUPING函数可以接受一列,返回0或者1。如果列值为空,那么GROUPING()返回1;如果列值非空,那么返回0。GROUPING只能在使用ROLLUP或CUBE的查询中使用。当需要在返回空值的地方显示某个值时,GROUPING()就非常有用。
1、在ROLLUP中对单列使用GROUPING()
select employee_id,sum(salary)
from employees
group by employee_id
order by employee_id;
--part of results:
EMPLOYEE_ID SUM(SALARY)
----------- -----------
100       24000
101       17000
102       17000
103        9000
104        6000
105        4800
106        4800
加上GROUPING来看看:
select grouping(employee_id),employee_id,sum(salary)
from employees
group by rollup(employee_id)
order by employee_id;
--part of results:
0         195        2800
0         196        3100
0         197        3000
0         198        2600
0         199        2600
0         200        4400
0         201       13000
0         202        6000
0         203        6500
0         204       10000
GROUPING(EMPLOYEE_ID) EMPLOYEE_ID SUM(SALARY)
--------------------- ----------- -----------
0         205       12000
0         206        8300
1               695051.47
2、使用CASE转换GROUPING()的返回值
可能你会觉得前面的0和1太枯燥了,代表不了任何意义,说白了就是不够人性化,呵呵。这个时候我们可以使用CASE来转换为一些有意义的值。
select
case grouping(employee_id)
when 1  then 'all divisions'
else to_char(employee_id)
end as div
,employee_id,sum(salary)
from employees
group by rollup(employee_id)
order by employee_id;
-----part of results:
DIV                                      EMPLOYEE_ID SUM(SALARY)
---------------------------------------- ----------- -----------
205                                              205       12000
206                                              206        8300
all divisions                                          695051.47
3、使用CASE和GROUPING()转换多个列的值
select
case grouping(employee_id)
when 1  then 'all divisions'
else to_char(employee_id)
end as div
,
case grouping(job_id)
when 1 then 'all jobs'
else job_id
end as job,
sum(salary)
from employees
group by rollup(employee_id,job_id)
order by employee_id,job_id;
-----part of results:
DIV                                      JOB        SUM(SALARY)
---------------------------------------- ---------- -----------
194                                      all jobs          3200
195                                      SH_CLERK          2800
195                                      all jobs          2800
196                                      SH_CLERK          3100
196                                      all jobs          3100
197                                      SH_CLERK          3000
197                                      all jobs          3000
198                                      SH_CLERK          2600
198                                      all jobs          2600
199                                      SH_CLERK          2600
199                                      all jobs          2600
200                                      AD_ASST           4400
200                                      all jobs          4400
201                                      MK_MAN           13000
201                                      all jobs         13000
202                                      MK_REP            6000
202                                      all jobs          6000
203                                      HR_REP            6500
203                                      all jobs          6500
204                                      PR_REP           10000
204                                      all jobs         10000
DIV                                      JOB        SUM(SALARY)
---------------------------------------- ---------- -----------
205                                      AC_MGR           12000
205                                      all jobs         12000
206                                      AC_ACCOUNT        8300
206                                      all jobs          8300
all divisions                            all jobs     695051.47
215 rows selected.
4、CUBE与GROUPING()结合使用
select
case grouping(employee_id)
when 1  then 'all divisions'
else to_char(employee_id)
end as div
,
case grouping(job_id)
when 1 then 'all jobs'
else job_id
end as job,
sum(salary)
from employees
group by cube(employee_id,job_id)
order by employee_id,job_id;
-----part of results:
DIV                                      JOB        SUM(SALARY)
---------------------------------------- ---------- -----------
194                                      all jobs          3200
195                                      SH_CLERK          2800
195                                      all jobs          2800
196                                      SH_CLERK          3100
196                                      all jobs          3100
197                                      SH_CLERK          3000
197                                      all jobs          3000
198                                      SH_CLERK          2600
198                                      all jobs          2600
199                                      SH_CLERK          2600
199                                      all jobs          2600
200                                      AD_ASST           4400
200                                      all jobs          4400
201                                      MK_MAN           13000
201                                      all jobs         13000
202                                      MK_REP            6000
202                                      all jobs          6000
203                                      HR_REP            6500
203                                      all jobs          6500
204                                      PR_REP           10000
204                                      all jobs         10000
DIV                                      JOB        SUM(SALARY)
---------------------------------------- ---------- -----------
205                                      AC_MGR           12000
205                                      all jobs         12000
206                                      AC_ACCOUNT        8300
206                                      all jobs          8300
all divisions                            AC_ACCOUNT        8300
all divisions                            AC_MGR           12000
all divisions                            AD_ASST           4400
all divisions                            AD_PRES          24000
all divisions                            AD_VP            34000
all divisions                            FI_ACCOUNT       39600
all divisions                            FI_MGR           12000
all divisions                            HR_REP            6500
all divisions                            IT_PROG          28800
all divisions                            MK_MAN           13000
all divisions                            MK_REP            6000
all divisions                            PR_REP           10000
all divisions                            PU_CLERK         13900
all divisions                            PU_MAN           11000
all divisions                            SA_MAN           61000
all divisions                            SA_REP       254151.47
all divisions                            SH_CLERK         64300
DIV                                      JOB        SUM(SALARY)
---------------------------------------- ---------- -----------
all divisions                            ST_CLERK         55700
all divisions                            ST_MAN           36400
all divisions                            all jobs     695051.47
234 rows selected.
5、使用GROUPING SETS子句
使用GROUPING SETS子句可以只返回小计记录:
select employee_id,job_id,sum(salary)
from employees
group by grouping sets(employee_id,job_id)
order by employee_id,job_id;
-----part of results:
EMPLOYEE_ID JOB_ID     SUM(SALARY)
----------- ---------- -----------
205                  12000
206                   8300
AC_ACCOUNT        8300
AC_MGR           12000
AD_ASST           4400
AD_PRES          24000
AD_VP            34000
FI_ACCOUNT       39600
FI_MGR           12000
HR_REP            6500
IT_PROG          28800
MK_MAN           13000
MK_REP            6000
PR_REP           10000
PU_CLERK         13900
PU_MAN           11000
SA_MAN           61000
SA_REP       254151.47
SH_CLERK         64300
ST_CLERK         55700
ST_MAN           36400
126 rows selected.
 --转自 
