Oracle 高级分组

1.rollup:rollup 是group by 的扩展,它只能出现在group by后面。主要是为了解决多层分组的问题。语法:
SELECT  . . . 
FROM  . . . 
GROUP BY ROLLUP (ordered list of grouping columns)
例如要查询每个部门的工资总和所有部门的总和
TEST@orcl> select dept_id,sum(salary) from employee group by rollup(dept_id);
   DEPT_ID SUM(SALARY)
---------- -----------
        10        8750
        20        9900
        30        9400
<null>           28050
如果rollup()有两列,将会有3个分组例如:
group by rollup(year,month)相当于
group by year,month
union
group by year
union
group by null;
----------------------------------------------
TEST@orcl> select year,month,sum(tot_sales) from all_orders
  2  group by rollup(year,month);
 
      YEAR      MONTH SUM(TOT_SALES)
---------- ---------- --------------
      2000          1        2997866
      2000          2        3325690
      2000          3        3719014
      2000          4        3497570
      2000          5        3640628
      2000          6        3146822
      2000          7        3446480
      2000          8        2973882
      2000          9        3207396
      2000         10        3193212
      2000         11        3096300
      2000         12        3278944
      2000 <null>           39523804
      2001          1        1498933
      2001          2        1662845
      2001          3        1859507
      2001          4        1748785
      2001          5        1820314
      2001          6        1573411
      2001          7        1723240
      2001          8        1486941
      2001          9        1603698
      2001         10        1596606
      2001         11        1548150
      2001         12        1639472
      2001 <null>           19761902
<null>     <null>           59285706
1.1 部分rollup:group by + 分组列 rollup(分组列表)
group by year ,rollup (month) 相当于
group by year ,month
union
group year;
  1  select year,month,sum(tot_sales) from all_orders
  2* group by year, rollup(month)
TEST@orcl> /
 
      YEAR      MONTH SUM(TOT_SALES)
---------- ---------- --------------
      2000          1        2997866
      2000          2        3325690
      2000          3        3719014
      2000          4        3497570
      2000          5        3640628
      2000          6        3146822
      2000          7        3446480
      2000          8        2973882
      2000          9        3207396
      2000         10        3193212
      2000         11        3096300
      2000         12        3278944
      2000 <null>           39523804
      2001          1        1498933
      2001          2        1662845
      2001          3        1859507
      2001          4        1748785
      2001          5        1820314
      2001          6        1573411
      2001          7        1723240
      2001          8        1486941
      2001          9        1603698
      2001         10        1596606
      2001         11        1548150
      2001         12        1639472
      2001 <null>           19761902
2.CUBE:cube类似于rollup,但产生的分组是分组类表的排列组合
SELECT  . . . 
FROM  . . . 
GROUP BY CUBE (list of grouping columns)
cube(year,month) 相当于
group by year,month
union
group by year
union
group by month
unin
group by null;
例子:
  1  select year,month,sum(tot_sales) from all_orders
  2* group by cube(year,month)
TEST@orcl> /
      YEAR      MONTH SUM(TOT_SALES)
---------- ---------- --------------
<null>     <null>           59285706
<null>              1        4496799
<null>              2        4988535
<null>              3        5578521
<null>              4        5246355
<null>              5        5460942
2.1 部分CUBE group by 分组列,cube(分组列表)
group by 后面的分组列可以看做一个固定列
3.GROUPING 函数,rollup和cube分组输出的结果是多级分组的,grouping函数能区分分组的级别。例如:
  1  select year,month,grouping(year) g_year,grouping(month) g_month from all_orders
  2* group by rollup(year,month)
TEST@orcl> /
      YEAR      MONTH     G_YEAR    G_MONTH
---------- ---------- ---------- ----------
      2000          1          0          0
      2000          2          0          0
      2000          3          0          0
      2000          4          0          0
      2000          5          0          0
      2000          6          0          0
      2000          7          0          0
      2000          8          0          0
      2000          9          0          0
      2000         10          0          0
      2000         11          0          0
      2000         12          0          0
      2000 <null>              0          1
      2001          1          0          0
      2001          2          0          0
      2001          3          0          0
      2001          4          0          0
      2001          5          0          0
      2001          6          0          0
      2001          7          0          0
      2001          8          0          0
      2001          9          0          0
      2001         10          0          0
      2001         11          0          0
      2001         12          0          0
      2001 <null>              0          1
<null>     <null>              1          1
grouping(分组列) 返回0或1,0:代表该分组列参加分组 1:不参加分组,grouping主要用在格式化输出 例如:
  1  select decode(grouping(year),1,'整年',year) year,decode(grouping(month),1,'整月',month) month
  2  from all_orders
  3* group by rollup(year,month)
TEST@orcl> /
YEAR                                     MONTH
---------------------------------------- ----------------------------------------
2000                                     1
2000                                     2
2000                                     3
2000                                     4
2000                                     5
2000                                     6
2000                                     7
2000                                     8
2000                                     9
2000                                     10
2000                                     11
2000                                     12
2000                                     整月
2001                                     1
2001                                     2
2001                                     3
2001                                     4
2001                                     5
2001                                     6
2001                                     7
2001                                     8
2001                                     9
2001                                     10
2001                                     11
2001                                     12
2001                                     整月
整年                                     整月
4.grouping sets:类似于rollup和cube
grouping sets(year,monh) 相当于
group by year
union
group by month
例如:
  1  select decode(grouping(year),1,'整年',year) year,decode(grouping(month),1,'整月',month) month
  2  from all_orders
  3* group by grouping sets(year,month)
TEST@orcl> /
YEAR                                     MONTH
---------------------------------------- ----------------------------------------
整年                                     1
整年                                     11
整年                                     6
整年                                     2
整年                                     4
整年                                     5
整年                                     8
整年                                     3
整年                                     7
整年                                     10
整年                                     12
整年                                     9
2001                                     整月
2000                                     整月
5.GROUP_ID和GROUPING_ID函数
 5.1 GROUPING_ID函数:
  语法:
SELECT  . . .  , GROUPING_ID(ordered_list_of_grouping_columns)
FROM  . . . 
GROUP BY  . . .
grouping_id函数和grouping函数相关联的,grouping函数返回的是0或者1,grouping_id 返回的就是对应列的grouping的值然后再组合,最后转换成十进制。例如:
  1  select year,month,grouping(year) g_year,grouping(month) g_month  from all_orders
  2   where year=2000
  3*  group by rollup(year,month)
SQL> /
 
      YEAR      MONTH     G_YEAR    G_MONTH
---------- ---------- ---------- ----------
      2000          1          0          0
      2000          2          0          0
      2000          3          0          0
      2000          4          0          0
      2000          5          0          0
      2000          6          0          0
      2000          7          0          0
      2000          8          0          0
      2000          9          0          0
      2000         10          0          0
      2000         11          0          0
      YEAR      MONTH     G_YEAR    G_MONTH
---------- ---------- ---------- ----------
      2000         12          0          0
      2000                     0          1
                               1          1
grouping_id(year,month)就是将G_YEAR和G_MONTH的值用||连接起来,因为grouping返回的0或1,可以看出是2进制,最终的结果会以十进制展示,例如:
 
  1  select year,month,grouping(year) g_year,grouping(month) g_month,grouping_id(year,month) g_y_m,
  2  grouping_id(month,year) g_m_y  from all_orders
  3   where year=2000
  4*  group by rollup(year,month)
SQL> /
 
      YEAR      MONTH     G_YEAR    G_MONTH      G_Y_M      G_M_Y
---------- ---------- ---------- ---------- ---------- ----------
      2000          1          0          0          0          0
      2000          2          0          0          0          0
      2000          3          0          0          0          0
      2000          4          0          0          0          0
      2000          5          0          0          0          0
      2000          6          0          0          0          0
      2000          7          0          0          0          0
      2000          8          0          0          0          0
      2000          9          0          0          0          0
      2000         10          0          0          0          0
      2000         11          0          0          0          0
 
      YEAR      MONTH     G_YEAR    G_MONTH      G_Y_M      G_M_Y
---------- ---------- ---------- ---------- ---------- ----------
      2000         12          0          0          0          0
      2000                     0          1          1          2
                               1          1          3          3
其作用可以用来过滤返回的分组级别。
 5.2 GROUP_ID
  语法:
SELECT  . . .  , GROUP_ID( )
FROM  . . . 
GROUP BY  . . .
group_id 分组可以识别哪些是重复的分组,唯一的分组返回0,例如:
 1  select year,month,grouping(year) g_year,grouping(month) g_month,group_id() g from all_orders
 2   where year=2000
 3*  group by year ,rollup(year,month)
QL> /
 
     YEAR      MONTH     G_YEAR    G_MONTH          G
--------- ---------- ---------- ---------- ----------
     2000          1          0          0          0
     2000          2          0          0          0
     2000          3          0          0          0
     2000          4          0          0          0
     2000          5          0          0          0
     2000          6          0          0          0
     2000          7          0          0          0
     2000          8          0          0          0
     2000          9          0          0          0
     2000         10          0          0          0
     2000         11          0          0          0
 
     YEAR      MONTH     G_YEAR    G_MONTH          G
--------- ---------- ---------- ---------- ----------
     2000         12          0          0          0
     2000                     0          1          0
     2000                     0          1          1
可以用 HAVING GROUP_ID() < 1过滤掉重复的分组。
原文地址:https://www.cnblogs.com/likeju/p/5044643.html