GROUP函数-GROUP_ID,GROUPING,GROUPING_ID
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 ('','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的更多相关文章
- 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 ...
- SQL Server ->> GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID
在我们制作报表的时候常常需要分组聚合.多组聚合和总合.如果通过另外的T-SQL语句来聚合难免性能太差.如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生 ...
- Group By 多个分组集小结 --GROUPING SETS,GROUP BY CUBE,GROUP BY ROLLUP,GROUPING(),GROUPING_ID()
T-SQL 多个分组集共有三种 GROUPING SETS, CUBE, 以及ROLLUP, 其中 CUBE和ROLLUP可以当做是GROUPING SETS的简写版 示例数据库下载: http:// ...
- GROUP函数
GROUP_ID 首先我们看看官方的解释: 大意是GROUP_ID用于区分相同分组标准的分组统计结果. 解释起来比较抽象,下面我们来看看具体的案例. 例1:单一分组 SQL> select gr ...
- SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE
1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...
- SQL 2012 Group By Rollup, Grouping
GO alter proc [zsp_BranchsData] as begin /* CREATE TABLE [原始机构数据] ( [序号] [varchar](50) NULL, [一级分行号] ...
- Hive函数:GROUPING SETS,GROUPING__ID,CUBE,ROLLUP
参考:lxw大数据田地:http://lxw1234.com/archives/2015/04/193.htm 数据准备: CREATE EXTERNAL TABLE test_data ( mont ...
- Oracle的 listagg() WITHIN GROUP ()函数使用
1.使用条件查询 查询部门为20的员工列表 -- 查询部门为20的员工列表 SELECT t.DEPTNO,t.ENAME FROM SCOTT.EMP t where t.DEPTNO = ...
- 关于MySQL的行转列的简单应用(二)---group函数
MySQL的行转列.列转行.连接字符串 concat.concat_ws.group_concat函数用法使用方法:CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一 ...
随机推荐
- log4net写入mysql完整例子
1,创建表log CREATE TABLE `log` ( `id` int(11) NOT NULL AUTO_INCREMENT , `log_datetime` timestamp NO ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- 正确获取访问者ip
使用$_SERVER['REMOTE_ADDR']获取访问者ip具有局限性.比如访问者系统位于docker环境时,$_SERVER['REMOTE_ADDR']获取到的ip为虚拟ip,而不是我们真正需 ...
- html5、canvas绘制本地时钟
效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- You are attempting to run the 32-bit installer on a 64-bit version of Window
您正试图在64位版本的窗口中运行32位安装程序. 系统有32位操作系统和64位操作系统的分别,相同的软件的安装也需要区分操作操作系统的位数. 解决办法:查看自己系统类型,根据类型下载安装相应位数的软件 ...
- Visual Studio跨平台开发Xamarin
台湾微软的一系列Visual Studio跨平台开发Xamarin的资料,上面还有视频.具体参看 http://www.microsoft.com/taiwan/newsletter/library/ ...
- 在Visual Studio中将现有.NET Framework项目迁移至.NET Core 1.1 Preview 1
1)下载安装包含 .NET Core 1.1 Preview 1 的 SDK:Windows x64 安装包(下载地址列表) 2)下载最新 VS 2015 NuGet 插件:https://dist. ...
- python自动化测试(4)-使用第三方python库技术实现
python自动化测试(4)-使用第三方python库技术实现 1 概述 关于测试的方法论,都是建立在之前的文章里面提到的观点: 功能测试不建议做自动化 接口测试性价比最高 接口测试可以做自动化 ...
- 免杀后门之MSF&Veil-Evasion的完美结合
本文由“即刻安全”投稿到“玄魂工作室” Veil-Evasion 是 Veil-Framework 框架的一部分,也是其主要的项目.利用它我们可以生成绕过杀软的 payload !kali 上并未安装 ...
- 剑指Offer面试题:7.旋转数组的最小数字
一.题目:旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2 ...