1、grouping使用
使用grouping可以判断该行是数据库中本来的行,还是有统计产生的行
SQL> select grouping(grade),grade,sum(num) from a group by rollup (grade);
GROUPING(GRADE) GRADE SUM(NUM)
--------------- ----- ----------
0 a 3
0 b 8
1 11
可以看出grouping值为0时说明这个值是数据库中本来的值,为1说明是统计的结果(也可以说该列为空时是1,不为空时是0),根据这一特性,我们可以使显示结果更加人性化
select decode(grouping(grade),'0',grade,'1','总计'),sum(num) from a group by rollup (grade);
或
select case grouping(grade) when 1 then '总计' else grade end as grade,sum(num) from a group by rollup (grade);
GRADE SUM(NUM)
----- ----------
a 3
b 8
总计 11
grouping中只能有一个参数
2、grouping_id
SQL> select grouping(grade),grouping(id),grouping_id(grade,id),grade,id,sum(num) from a group by rollup (grade,id);
GROUPING(GRADE) GROUPING(ID) GROUPING_ID(GRADE,ID) GRADE ID SUM(NUM)
--------------- ------------ --------------------- ----- ----- ----------
0 0 0 a 1 1
0 0 0 a 2 2
0 1 1 a 3
0 0 0 b 2 4
0 0 0 b 3 4
0 1 1 b 8
1 1 3 11
SQL> select grouping(grade),grouping(id),grouping_id(id,grade),grade,id,sum(num) from a group by rollup (grade,id);
GROUPING(GRADE) GROUPING(ID) GROUPING_ID(ID,GRADE) GRADE ID SUM(NUM)
--------------- ------------ --------------------- ----- ----- ----------
0 0 0 a 1 1
0 0 0 a 2 2
0 1 2 a 3
0 0 0 b 2 4
0 0 0 b 3 4
0 1 2 b 8
1 1 3 11
会发现grouping_id(id,grade)和grouping_id(grade,id)的值是不同的,因为GROUPING_ID()函数可以接受一列或多列,返回GROUPING位向量的十进制值。GROUPING位向量的计算方法是将按照顺序对每一列调用GROUPING函数的结果组合起来,所以说01和10的值不一样的
GOURPING位向量计算
如下例所示
grade id 位向量 GROUPING_ID()返回值
非空 非空 00 0
非空 空 01 1
空 非空 10 2
空 空 11 3
三个参数的显示结果
SQL> select grade,grade1,id,grouping_id(grade,grade1),sum(num) from a group by rollup (grade,grade1,id);
GRADE GRADE1 ID GROUPING_ID(GRADE,GRADE1) SUM(NUM)
----- ------ ----- ------------------------- ----------
a a1 1 0 1
a a1 2 0 2
a a1 0 3
a 1 3
b b1 2 0 4
b b1 0 4
b b2 3 0 4
b b2 0 4
b 1 8
3 11
10 rows selected
SQL> select grade,grade1,id,grouping_id(grade,grade1,id),sum(num) from a group by rollup (grade,grade1,id);
GRADE GRADE1 ID GROUPING_ID(GRADE,GRADE1,ID) SUM(NUM)
----- ------ ----- ---------------------------- ----------
a a1 1 0 1
a a1 2 0 2
a a1 1 3
a 3 3
b b1 2 0 4
b b1 1 4
b b2 3 0 4
b b2 1 4
b 3 8
7 11
grouping_id也可以理解为统计结果的级别
3、使用grouping_id
(1)使显示人性化
select grade,decode(grouping_id(grade,id),'0',id,'1','小计','3','总计'),sum(num) from a group by rollup (grade,id);
GRADE DECODE(GROUPING_ID(GRADE,ID),' SUM(NUM)
----- ------------------------------ ----------
a 1 1
a 2 2
a 小计 3
b 2 4
b 3 4
b 小计 8
总计 11
(2)去除不是小计或总计的值
select grade,decode(grouping_id(grade,id),'0',id,'1','小计','3','总计'),sum(num)
from a
group by rollup (grade,id)
having grouping_id(grade,id)>0
GRADE DECODE(GROUPING_ID(GRADE,ID),' SUM(NUM)
----- ------------------------------ ----------
a 小计 3
b 小计 8
总计 11
4、group_id的使用
当group by子句中重复使用一个列时
SQL> select grade,id,sum(num) from a group by grade,rollup (grade,id);
GRADE ID SUM(NUM)
----- ----- ----------
a 1 1
a 2 2
b 2 4
b 3 4
a 3
b 8
a 3
b 8
看出后面两行的值和前面两行的只是相同的,我们可以通过group_id来去除重复值
SQL> select grade,id,group_id(),sum(num) from a group by grade,rollup (grade,id);
GRADE ID GROUP_ID() SUM(NUM)
----- ----- ---------- ----------
a 1 0 1
a 2 0 2
b 2 0 4
b 3 0 4
a 0 3
b 0 8
a 1 3
b 1 8
SQL> select grade,id,sum(num) from a group by grade,rollup (grade,id) having group_id()=0;
GRADE ID SUM(NUM)
----- ----- ----------
a 1 1
a 2 2
b 2 4
b 3 4
a 3
b 8
GROUP_ID()唯一标识重复组