GROUP_ID

首先我们看看官方的解释:

大意是GROUP_ID用于区分相同分组标准的分组统计结果。

解释起来比较抽象,下面我们来看看具体的案例。

例1:单一分组

  1. SQL> select group_id(),deptno,sum(sal) from emp group by rollup(deptno);
  2.  
  3. GROUP_ID() DEPTNO SUM(SAL)
  4. ---------- ---------- ----------
  5. 0 10 8750
  6. 0 20 10875
  7. 0 30 9400
  8. 0 29025

rollup(deptno)只是一个唯一的分组,所以产生的group_id()为0,代表这是同一个分组的结果。

下面我们来看看重复分组的情况

例2:重复分组

  1. SQL> select group_id(),deptno,sum(sal) from emp group by rollup(deptno,deptno);
  2.  
  3. GROUP_ID() DEPTNO SUM(SAL)
  4. ---------- ---------- ----------
  5. 0 10 8750
  6. 0 20 10875
  7. 0 30 9400
  8. 1 10 8750
  9. 1 20 10875
  10. 1 30 9400
  11. 0 29025
  12.  
  13. 7 rows selected.

group_id()为1代表这些是重复的分组。

注意:可通过having group_id() <1来剔除重复的分组。

老实说,我也看不出GROUP_ID在实际工作中的应用场景,姑且先记着。

GROUPING

其语法为:GROUPING(expr)

下面我们来看看官方的解释:

即GROUPING函数用于区分分组后的普通行和聚合行。如果是聚合行,则返回1,反之,则是0。

下面我们来看看具体的案例:

  1. SQL> select grouping(deptno),grouping(job),deptno,job,sum(sal) from emp group by rollup(deptno,job);
  2.  
  3. GROUPING(DEPTNO) GROUPING(JOB) DEPTNO JOB SUM(SAL)
  4. ---------------- ------------- ---------- --------- ----------
  5. 0 0 10 CLERK 1300
  6. 0 0 10 MANAGER 2450
  7. 0 0 10 PRESIDENT 5000
  8. 0 1 10 8750
  9. 0 0 20 CLERK 1900
  10. 0 0 20 ANALYST 6000
  11. 0 0 20 MANAGER 2975
  12. 0 1 20 10875
  13. 0 0 30 CLERK 950
  14. 0 0 30 MANAGER 2850
  15. 0 0 30 SALESMAN 5600
  16. 0 1 30 9400
  17. 1 1 29025
  18.  
  19. 13 rows selected.

首先我们看GROUPING(DEPTNO)这一列的结果,不难看出,凡是基于DEPTNO的汇总,GROUPING的结果均为0,因为最后一行是总的汇总,所以GROUPING的值为1.

基于这个逻辑,可以看出GROUPING(JOB)的值也是吻合的。

GROUPING_ID

GROUPING_ID是GROUPING的增强版,与GROUPING只能带一个表达式不同,它能带多个表达式。

语法如下:

GROUPING_ID(expr1, expr2, expr3,….)

下面我们来看看官方的解释:

GROUPING_ID在功能上相当于将多个GROUPING函数的结果串接成二进制数,返回的是这个二进制数对应的十进制数。

下面我们来看看具体的案例:

  1. SQL> select grouping(deptno)g_d,grouping(job)g_j,grouping_id(deptno)gi_d,grouping_id(job)gi_j,grouping_id(deptno,job)gi_dj,grouping_id(job,deptno)gi_jd,deptno,job,sum(sal) from emp group by cube(deptno,job);
  2.  
  3. G_D G_J GI_D GI_J GI_DJ GI_JD DEPTNO JOB SUM(SAL)
  4. ---------- ---------- ---------- ---------- ---------- ---------- ---------- --------- ----------
  5. 1 1 1 1 3 3 29025
  6. 1 0 1 0 2 1 CLERK 4150
  7. 1 0 1 0 2 1 ANALYST 6000
  8. 1 0 1 0 2 1 MANAGER 8275
  9. 1 0 1 0 2 1 SALESMAN 5600
  10. 1 0 1 0 2 1 PRESIDENT 5000
  11. 0 1 0 1 1 2 10 8750
  12. 0 0 0 0 0 0 10 CLERK 1300
  13. 0 0 0 0 0 0 10 MANAGER 2450
  14. 0 0 0 0 0 0 10 PRESIDENT 5000
  15. 0 1 0 1 1 2 20 10875
  16. 0 0 0 0 0 0 20 CLERK 1900
  17. 0 0 0 0 0 0 20 ANALYST 6000
  18. 0 0 0 0 0 0 20 MANAGER 2975
  19. 0 1 0 1 1 2 30 9400
  20. 0 0 0 0 0 0 30 CLERK 950
  21. 0 0 0 0 0 0 30 MANAGER 2850
  22. 0 0 0 0 0 0 30 SALESMAN 5600
  23.  
  24. 18 rows selected.

大家看到这个案例估计都有点晕。。。

之所以这样提供,是为了呈现一个直观的结果进行对比。

解读这个结果,需要注意以下两点:

1> 若本行是某expr的汇总,那么该expr对应的二进制数位置为0否则置为1。

2> GROUPING_ID(expr1, expr2, expr3,….)的值其实是对应GROUPING(expr1),GROUPING(expr2),GROUPING(expr3)...值的串接。

首先看第一列,第三列,虽然一个是grouping(deptno),一个是grouping_id(deptno),因为只有一个表达式,所以两者的结果是一样的。第二列,第四列同样如此。

第五列的结果是第一列和第二列的数值的串接,然后返回的十进制数,以第二行为例,GI_DJ=2其实是二进制10转化为十进制后的数,其中1为G_D的值,0为G_J的值。

而GI_JD=1则是二进制01转化为十进制后的数,其中0为G_J的值,1为G_D的值。注意,串接的顺序为GROUPING_ID中表达式的顺序。

说了这么多,下面我们来看一个利用GROUPING_ID实现行列转换的案例。

  1. with t as
  2. ( select grouping_id(deptno,job)gi_dj,deptno,job,count(*)cnt
  3. from emp group by cube(deptno,job)),
  4. t1 as
  5. ( select decode(gi_dj,0,deptno,1,deptno,99) deptno,decode(gi_dj,1,cnt,3,cnt)sub_total,
  6. decode(job,'CLERK',cnt) c1,decode(job,'ANALYST',cnt)c2,decode(job,'MANAGER',cnt)c3,
  7. decode(job,'SALESMAN',cnt)c4,decode(job,'PRESIDENT',cnt)c5
  8. from t)
  9. select deptno,max(sub_total) sub_total,max(c1)clerk,max(c2)analyst,
  10. max(c3)manager,max(c4)salesman,max(c5)president
  11. from t1 group by deptno order by deptno;

最后生成的结果如下:

  1. DEPTNO SUB_TOTAL CLERK ANALYST MANAGER SALESMAN PRESIDENT
  2. ---------- ---------- ---------- --------- ---------- ---------- ----------
  3. 10 3 1 1 1
  4. 20 5 2 2 1
  5. 30 6 1 1 4
  6. 99 14 4 2 3 4 1

其中,99代表合计,sub_total代表小计。这种统计类的需求在实际生产中还是应用蛮广的。

当然,该结果也可利用PIVOT函数实现,具体语句如下:

  1. with t as(select grouping_id(deptno,job)gi_dj,deptno,job,count(*)cnt from emp group by cube(deptno,job)),
  2. t1 as (select decode(gi_dj,0,deptno,1,deptno,99)deptno,decode(gi_dj,0,job,2,job,9)job,cnt from t)
  3. select * from (select * from t1)pivot(sum(cnt)for job in ('','CLERK','ANALYST','MANAGER','SALESMAN','PRESIDENT')) order by deptno;

参考资料:

1> http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions070.htm#SQLRF00646

2> http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions071.htm#SQLRF00647

3> http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions072.htm#SQLRF00648

GROUP函数-GROUP_ID,GROUPING,GROUPING_ID的更多相关文章

  1. oracle group by rollup,decode,grouping,nvl,nvl2,nullif,grouping_id,group_id,grouping sets,RATIO_TO

    干oracle 047文章12当问题,经验group by 声明.因此邂逅group by  rollup,decode,grouping,nvl,nvl2,nullif,RATIO_TO_REPOR ...

  2. SQL Server ->> GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID

    在我们制作报表的时候常常需要分组聚合.多组聚合和总合.如果通过另外的T-SQL语句来聚合难免性能太差.如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生 ...

  3. Group By 多个分组集小结 --GROUPING SETS,GROUP BY CUBE,GROUP BY ROLLUP,GROUPING(),GROUPING_ID()

    T-SQL 多个分组集共有三种 GROUPING SETS, CUBE, 以及ROLLUP, 其中 CUBE和ROLLUP可以当做是GROUPING SETS的简写版 示例数据库下载: http:// ...

  4. GROUP函数

    GROUP_ID 首先我们看看官方的解释: 大意是GROUP_ID用于区分相同分组标准的分组统计结果. 解释起来比较抽象,下面我们来看看具体的案例. 例1:单一分组 SQL> select gr ...

  5. SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

    1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...

  6. SQL 2012 Group By Rollup, Grouping

    GO alter proc [zsp_BranchsData] as begin /* CREATE TABLE [原始机构数据] ( [序号] [varchar](50) NULL, [一级分行号] ...

  7. Hive函数:GROUPING SETS,GROUPING__ID,CUBE,ROLLUP

    参考:lxw大数据田地:http://lxw1234.com/archives/2015/04/193.htm 数据准备: CREATE EXTERNAL TABLE test_data ( mont ...

  8. Oracle的 listagg() WITHIN GROUP ()函数使用

    1.使用条件查询  查询部门为20的员工列表 -- 查询部门为20的员工列表    SELECT t.DEPTNO,t.ENAME FROM SCOTT.EMP t where t.DEPTNO = ...

  9. 关于MySQL的行转列的简单应用(二)---group函数

    MySQL的行转列.列转行.连接字符串  concat.concat_ws.group_concat函数用法使用方法:CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一 ...

随机推荐

  1. List<T>Find方法,FindAll方法,Contains方法,Equals方法

    假如传入的T是一个类, List<MessageInfos> MessageInfos = new List<MessageInfos>(); MessageInfos= Me ...

  2. 4_jquery

    官网:www.jquery.com 兼容: 1.jquery-3.1.0.js :form.attr("checked","false")无效 2.firefo ...

  3. <十二>JDBC_批量处理

    import java.sql.Connection;import java.sql.PreparedStatement;import org.junit.Test;import com.kk.jdb ...

  4. tab

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. WUI 前端组件

    为什么会有WUI前端组件,我们接触的UI组件如:YUI.EXTjs.EasyUI,这些组件虽然提供了丰富的UI,并且一定程度上缩短了开始时间,单这些组件提供的页面风格是统一的,我们的产品风格不可能像这 ...

  6. java异常处理

    try{}catch(){}中的代码与外部代码之间有一定的逻辑关系,需要考虑到如果抛出异常的情况下,外部代码是否可以执行. 在需要捕获异常前尽量不要代入非异常代码,捕获后相关的代码放在一起.

  7. 《.NET之美》消息及勘误

    <.NET之美>消息及勘误 编辑最终还是采用了<.NET之美>作为书名,尽管我一直觉得这个名字有点文艺了,而更倾向于使用<.NET专题解析>这个名称. 目前已经可以 ...

  8. 分区里的inode号是0号和1号的block

    分区里的inode号是0号和1号的block 我相信大家在使用Linux的时候都遇到过误删文件系统数据的情况,不管是自己误删还是帮人家恢复误删 现在用的比较多的恢复工具大概是ext3grep .ext ...

  9. 8天掌握EF的Code First开发之Entity Framework介绍

    返回<8天掌握EF的Code First开发>总目录 本篇目录 Entity Framework概要 什么是ORM Entity Framework简史 Entity Framework具 ...

  10. R in Action 读书笔记(6)基本图形

    MindMapper原文件