Oracle 高级分组group by cube拓展
Oracle的cube拓展功能会将cube()里指定的每一列按照顺序替换成null值,并返回指定列的所有组合。
oracle的cube分组拓展主要用于替换需要通过union all和goup by 组合来实现业务功能的场景。通过该函数可以节省代码量,且使代码更加简洁。
实验过程如下:
首先看一下A表的内容:
HR@ORA11GR2 > select * from a;
A A2 A3
---------- ---------- ----------
1 4 5
2 4 6
3 4 7
4 5 9
5 5 10
6 5 11
7 5 12
8 5 13
8 rows selected.
若要通过union all 来实现数据组合功能:
HR@ORA11GR2 > with temp as (
2 select a, a2 from a
3 union all
4 select a , null a2 from a
5 union all
6 select null a , a2 from a
7 union all
8 select null a , null a2 from a
9 )
10 select * from temp group by a, a2 order by a2 desc;
A A2
---------- ----------
1
2
3
4
5
6
7
8
4 5
5 5
A A2
---------- ----------
6 5
7 5
8 5
5
1 4
2 4
3 4
4
19 rows selected.
使用cube分组拓展结果:
HR@ORA11GR2 > select a, a2 from a group by cube(a, a2) order by a2 desc;
A A2
---------- ----------
1
2
3
4
5
6
7
8
4 5
5 5
A A2
---------- ----------
6 5
7 5
8 5
5
1 4
2 4
3 4
4
19 rows selected.
从上面的输出中,我们会发现cube会将许多的null值,如果cube()里指定的列本身就具有null值,又需要如何区分呢?
解决方法为通过grouping()函数来排除null值,例如grouping(a)来检测A表中a列是否有一行null值是由cube产生的,如果有,则返回1,其他所有情况,则返回0.
接着再结合decode()函数或case表达式,来将cube()产生的null值转化成通俗易懂的字符串。
实验如下:
HR@ORA11GR2 > select decode(grouping(a),1,'cube_value',a) a , decode(grouping(a2), 1, 'cube_value',a2) a2 from a group by cube(a, a2) order by a2 desc;
A A2
---------------------------------------- ----------------------------------------
cube_value cube_value
4 cube_value
8 cube_value
7 cube_value
6 cube_value
5 cube_value
3 cube_value
2 cube_value
1 cube_value
cube_value 5
6 5
A A2
---------------------------------------- ----------------------------------------
8 5
7 5
4 5
5 5
1 4
cube_value 4
3 4
2 4
19 rows selected.