Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。如果是ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。如果是GROUP BY CUBE(A, B, C),则首先会对
Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。如果是ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP
BY操作。 grouping_id()可以美化效果。
一、CUBE和ROLLUP
例子:
SELECT
MANAGER_ID, DEPARTMENT_ID, SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20,30)
GROUP BY CUBE(DEPARTMENT_ID,MANAGER_ID)
返回结果:
MANAGER_ID DEPARTMENT_ID DD
43700
100 24000
114 13700
201 6000
20 19000
100 20 13000
201 20 6000
30
24700
100 30 11000
114 30 13700
二、利用GROUPING美化数据结果
SELECT
GROUPING(MANAGER_ID) G_MANAGER_ID,
GROUPING(DEPARTMENT_ID) G_DEPARTMENT_ID,
MANAGER_ID,
DEPARTMENT_ID,
SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20,30)
GROUP BY CUBE(DEPARTMENT_ID,MANAGER_ID)
返回结果:
为NULL的地方GROUPING()填充1。
三、GROUPING_ID()函数可以接受一列或多列,返回GROUPING位向量的十进制值
例子:
SELECT
GROUPING(DEPARTMENT_ID) W,
GROUPING(MANAGER_ID) Q,
GROUPING(DEPARTMENT_ID) || GROUPING(MANAGER_ID) E,
GROUPING_ID(DEPARTMENT_ID, MANAGER_ID) R,
MANAGER_ID,
DEPARTMENT_ID,
SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20,30)
GROUP BY CUBE(DEPARTMENT_ID,MANAGER_ID)
返回结果:
利用GROUPING_ID()函数特性,过滤只有小计和合计的行数据:
SELECT
GROUPING(DEPARTMENT_ID) W,
GROUPING(MANAGER_ID) Q,
GROUPING(DEPARTMENT_ID) || GROUPING(MANAGER_ID) E,
GROUPING_ID(DEPARTMENT_ID, MANAGER_ID) R,
MANAGER_ID,
DEPARTMENT_ID,
SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20,30)
GROUP BY CUBE(DEPARTMENT_ID,MANAGER_ID)
HAVING GROUPING_ID(DEPARTMENT_ID, MANAGER_ID) > 0
四、GROUP_ID() 函数可用于消除GROUP BY子句返回的重复记录。GROUP_ID()不接受任何参数。如果某个特定的分组重复出现n次,那么GROUP_ID()返回从0到n-1之间的一个整数。
先看不使用GROUP_ID()时的效果
SELECT
DEPARTMENT_ID,
MANAGER_ID,
GROUP_ID() D,
SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20)
GROUP BY DEPARTMENT_ID, CUBE(DEPARTMENT_ID,MANAGER_ID)
ORDER BY DEPARTMENT_ID,MANAGER_ID
返回结果:DEPARTMENT_ID为NULL的记录不在下面集合里面,但是有多了几条重复数据(D=1)
使用GROUP_ID()过滤数据,GROUP_ID() = 0
SELECT
DEPARTMENT_ID,
MANAGER_ID,
GROUP_ID(),
SUM(SALARY) DD
FROM EMPLOYEES EMP
WHERE DEPARTMENT_ID IN (20,30)
GROUP BY DEPARTMENT_ID, CUBE(DEPARTMENT_ID,MANAGER_ID)
HAVING GROUP_ID() = 0
ORDER BY DEPARTMENT_ID,MANAGER_ID
返回结果: