GROUP_ID

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

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

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

例1:单一分组

SQL> select group_id(),deptno,sum(sal) from emp group by rollup(deptno);

GROUP_ID()     DEPTNO    SUM(SAL)
---------- ---------- ----------
0 10 8750
0 20 10875
0 30 9400
0 29025

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

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

例2:重复分组

SQL> select group_id(),deptno,sum(sal) from emp group by rollup(deptno,deptno);

GROUP_ID()      DEPTNO    SUM(SAL)
---------- ---------- ----------
0 10 8750
0 20 10875
0 30 9400
1 10 8750
1 20 10875
1 30 9400
0 29025 7 rows selected.

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

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

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

GROUPING

其语法为:GROUPING(expr)

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

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

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

SQL> select grouping(deptno),grouping(job),deptno,job,sum(sal) from emp group by rollup(deptno,job);

GROUPING(DEPTNO) GROUPING(JOB)       DEPTNO JOB          SUM(SAL)
---------------- ------------- ---------- --------- ----------
0 0 10 CLERK 1300
0 0 10 MANAGER 2450
0 0 10 PRESIDENT 5000
0 1 10 8750
0 0 20 CLERK 1900
0 0 20 ANALYST 6000
0 0 20 MANAGER 2975
0 1 20 10875
0 0 30 CLERK 950
0 0 30 MANAGER 2850
0 0 30 SALESMAN 5600
0 1 30 9400
1 1 29025 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函数的结果串接成二进制数,返回的是这个二进制数对应的十进制数。

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

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);

       G_D        G_J        GI_D       GI_J      GI_DJ      GI_JD    DEPTNO  JOB         SUM(SAL)
---------- ---------- ---------- ---------- ---------- ---------- ---------- --------- ----------
1 1 1 1 3 3 29025
1 0 1 0 2 1 CLERK 4150
1 0 1 0 2 1 ANALYST 6000
1 0 1 0 2 1 MANAGER 8275
1 0 1 0 2 1 SALESMAN 5600
1 0 1 0 2 1 PRESIDENT 5000
0 1 0 1 1 2 10 8750
0 0 0 0 0 0 10 CLERK 1300
0 0 0 0 0 0 10 MANAGER 2450
0 0 0 0 0 0 10 PRESIDENT 5000
0 1 0 1 1 2 20 10875
0 0 0 0 0 0 20 CLERK 1900
0 0 0 0 0 0 20 ANALYST 6000
0 0 0 0 0 0 20 MANAGER 2975
0 1 0 1 1 2 30 9400
0 0 0 0 0 0 30 CLERK 950
0 0 0 0 0 0 30 MANAGER 2850
0 0 0 0 0 0 30 SALESMAN 5600 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实现行列转换的案例。

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

最后生成的结果如下:

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

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

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

with t as(select grouping_id(deptno,job)gi_dj,deptno,job,count(*)cnt from emp group by cube(deptno,job)),
t1 as (select decode(gi_dj,0,deptno,1,deptno,99)deptno,decode(gi_dj,0,job,2,job,9)job,cnt from t)
select * from (select * from t1)pivot(sum(cnt)for job in ('9','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函数的更多相关文章

  1. GROUP函数-GROUP_ID,GROUPING,GROUPING_ID

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

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

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

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

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

  4. Java正则表达式--Matcher.group函数的用法

    原来,group是针对()来说的,group(0)就是指的整个串,group(1) 指的是第一个括号里的东西,group(2)指的第二个括号里的东西. 最近学习正则表达式,发现Java中的一些术语与其 ...

  5. MongoDB中的group

    在Mongodb的查询中,有类似于SQL中group by功能的group函数.两者的功能有些类似,但是区别也是比较明显的. 对于SQL来说,group by的作用就是安装依据列来将数据表中的记录分成 ...

  6. MongoDB学习总结(三) —— 常用聚合函数

    上一篇介绍了MongoDB增删改查命令的基本用法,这一篇来学习一下MongoDB的一些基本聚合函数. 下面我们直奔主题,用简单的实例依次介绍一下. > count() 函数 集合的count函数 ...

  7. python第六天 函数 python标准库实例大全

    今天学习第一模块的最后一课课程--函数: python的第一个函数: 1 def func1(): 2 print('第一个函数') 3 return 0 4 func1() 1 同时返回多种类型时, ...

  8. mongodb mapredReduce 多个条件分组(group by)

    from:https://my.oschina.net/chiyong/blog/289138 Mongodb 没有传统数据库的group函数,如果分组需要走MapReduce.这种MR与Hadoop ...

  9. 文件属性,获取,设置文件属性chown stat函数

    转载:http://c.biancheng.net/cpp/html/326.html man 2 stat查看手册 int stat(const char *path, struct stat *b ...

随机推荐

  1. 加密解密(1)HTTPS与HTTP区别

    HTTPS简介 HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即 ...

  2. C# 操作Access的Ole对象[转]

    原文链接 OLE对象数据类型 (1)OLE 对象用于使用 OLE 协议在其他程序中创建的 OLE 对象,如 Microsoft Word 文档. Microsoft Excel 电子表格.图片.声音或 ...

  3. 转-Mac下Apache Tomcat安装配置

    ava Web如果稍微知道一点,一般对Tomcat都不会陌生,Apache是普通服务器,本身只支持html即普通网页,可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat ...

  4. thinkphp3.2 + soap

    服务器配置 扩展libxml2下载地址:http://xmlsoft.org/downloads.html 在windows下的php.ini文件里 找到这一行代码(如没有则自行添加) extensi ...

  5. Asp.Net识别手机访问

    在VS创建WEB应用程序时会有一个微软开发的典型web应用程序 在根目录有个用户控件用来实现切换手机和电脑 其中有个微软开发的类和方法用来专门判断移动设备和桌面设备 在Microsoft.AspNet ...

  6. Java操作pdf: JarsperReport的简单使用

    在企业级应用开发中,报表生成.报表打印下载是其重要的一个环节.除了 Excel 报表之外,PDF 报表也有广泛的应用场景. 目前世面上比较流行的制作 PDF 报表的工具如下: iText PDF :i ...

  7. Map接口框架图

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  8. install nginx error

    the error info : the HTTP gzip module requires the zlib library.You can either disable the module by ...

  9. 用yunio网盘搭建git私有仓库

      研究生开始奔波于教研室和寝室之间,于是想搭建一个git私有仓库来管理自己在做的项目或者学习资料.一来可以很方便的管理项目,二来可以学习使用git.我的主要工作平台是Linux,这也是我选择yuni ...

  10. oracle 执行跟踪

    一.sql_trace的介绍 --打开trace文件设置,把sql trace设置为true,就会在udump目录中增加一个trc文件.alter session set sql_trace=true ...