使用group by rollup和group by cube后的辅助函数
本文主要介绍,报表在使用group by rollup和group by cube后的辅助函数。
CREATE TABLE TEST8
(
"ID" NUMBER,
"ORDERID" NUMBER,
"PRODUCTID" NUMBER,
"PRICE" NUMBER(10,2),
"QUANTITY" NUMBER
)
insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (1, 1, 1, 3, 10);
insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (2, 1, 2, 4, 5);
insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (3, 1, 3, 10, 2);
insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (4, 2, 1, 3, 6);
insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (5, 2, 2, 4, 6);
基础数据
1、GROUPING函数
使用GROUPING函数处理汇总结果(在使用group by rollup和group by cube后的结果集)中的空值。
select orderid,productid,count(orderid) ordercount from test8 group by cube(orderid,productid) order by orderid;

结果集按照orderid和productid进行汇总之后,出现了很多的空值,具体原因参考哥前面的随笔 ,so,必须解决这个问题,因为null值对报表结果来说没什么用,我们大致都会用0,'空','NULL'之类,来表示空值,所以GROUPING函数就是来干这个的.看代码:
select GROUPING(orderid) orderid,productid,count(orderid) ordercount from test8 group by cube(orderid,productid) order by orderid;
对比上面的没有使用GROUPING函数的结果集我们发现
当orderid为null值的时候grouping(orderid)的值为1,反之为0
所以:根据这个特点我们可以推断出GROUPING函数的用法:
GROUPING(字段),如果字段值为null,GROUPING(字段)返回1,反之返回0。
通过GROUPING(字段名)的这个特点,在结果case when then else end函数,就可以将null值修改为任何字段名类型的值了,代码如下:
select case GROUPING(orderid) when 1 then 0 else orderid end orderid,productid,count(orderid) ordercount from test8 group by cube(orderid,productid) order by orderid;
null值全部改为了0
2、GROUPING SETS函数
和哥前面的随笔一样,不知道它的功能没关系,先试一试,在根据结果集推出来他的功能,不多说,上代码:
i、现在需要求出每个订单下每个产品的订单数
(1)group by解决方法:
select orderid,productid,count(orderid) from test8 group by (orderid,productid) order by orderid

(2)group by grouping sets解决方案
这边因为不知道他的功能,那么就直接上代码猜:
a、猜想一:grouping sets(orderid,productid)
select orderid,productid,count(orderid) from test8 group by grouping sets(orderid,productid) order by orderid
根据结果集很容易的发现,group by grouping sets(orderid,productid)的结果集等于group by orderid 和group by productid的合集,
下面验证猜想:
select orderid,null productid,count(orderid) ordercount from test8 group by(orderid)
union
select null orderid,productid,count(orderid) ordercount from test8 group by(productid)

ok,我们的猜想是正确,但是grouping sets(orderid,productid)并不能解i的需求,于是继续猜
b、猜想二:group by grouping sets(orderid,productid)
select orderid,productid,count(orderid) ordercount from test8 group by grouping sets((orderid,productid)) order by orderid

ok,猜想二符合i提出的需求
ii、总结grouping sets的功能
根据上面的猜想大致可以推出grouping sets的功能:grouping by是group by的集合
GROUP BY GROUPING SETS (A,B,C) 等价与 GROUP BY A
UNION ALL
GROUP BY B
UNION ALL
GROUP BY C
注意:grouping sets的特殊用法,grouping sets内部的最小单位是单个字段,其次是一个多个字段的几个用(字段1,字段2,......)表示,但是不支持嵌套括号,也没有必要,因为大多数情况下的报表都是2维的。
GROUP BY GROUPING SETS ((A,B,C)) 等价与 GROUP BY A,B,C GROUP BY GROUPING SETS (A,(B,C)) 等价与 GROUP BY A
UNION ALL
GROUP BY B,C
我们还可以混合使用,如下:
GROUP BY A 等价于 GROUP BY A
,B ,B
,GROUPING SETS ((B,C)) ,C GROUP BY A 等价于 GROUP BY A,B,C
,B UNION ALL
,GROUPING SETS (B,C) GROUP BY A,B GROUP BY A 等价于 GROUP BY A,B,C
,B UNION ALL
,C GROUP BY A,B,C
,GROUPING SETS (B,C)
iii、Group by Grouping sets解决的问题:
更加灵活的处理一些报表的统计工作,因为使用group by rollup 和group by cube都是固定格式的统计报表模式,当你给定三个需要分组统计的字段(A,B,C),前者是
select count(*) from tb ------->group by A------>group by B ------->group by C 然后将几个结果集union all一下,后者则是通过类似选择排序的方式联合结果集(不理解的话,参考哥前面的随笔),这两种统计模式不够灵活。
所以Group by Grouping sets就是一种足够灵活的方式,来获取我们想要的统计报表。
3、GROUP BY ,CUBE 或ROLLUP 中同时使用一列的处理
i、问题:在日常开发中可能会存在GROUP BY 或者GROUP BY CUBE 或者GROUP BY ROLLUP或者它们中组合使用到同一列的情况,那么就会出现重复的数据行,代码如下:
select orderid,productid,count(orderid) ordercount from test8 group by orderid,rollup(orderid,productid)
前面group by已经对orderid做了一次分组统计,后面rollup又对其做了一次分组统计,所以
出现了红框内的情况
ii、解决方案:
a、第一步:使用GROUP_ID()函数,这个函数的作用检索出每一个数据行在表中重复出现的次数,当然这个函数只在有GROUP BY或者GROUP BY ROLLUP 或者GROUP BY CUBE语句中的某一个存在的语句中可以使用,在其他语句中不能使用,代码如下:
select orderid,productid,GROUP_ID(),count(orderid) ordercount from test8 group by orderid,rollup(orderid,productid)
GROUP_ID()方法显示红框内的两条数据重复出现了一次,那么这两条数据就需要过滤
b、下面使用HAVING(相当于where,但是having只能用于分组函数的数据过滤,只能用于包含group by的语句中) 来过滤重复的数据,代码如下:
select orderid,productid,GROUP_ID(),count(orderid) ordercount from test8 group by orderid,rollup(orderid,productid) HAVING GROUP_ID()=0

ok,数据成功过滤
使用group by rollup和group by cube后的辅助函数的更多相关文章
- Oracle Group by+rollup+cube 的应用
首先我们创建一个示例表: Create table test_group (v_name varchar2(4) ,v_size varchar2(4) ,v_color varchar2(4) ,n ...
- 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 BY ROLLUP和CUBE 用法
ROLLUP和CUBE 用法 Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是Group by ROLLUP(A, B, C)的话 ...
- 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 ...
- Group By Rollup
Rollup与group by组合使用,可对分组结果进行进一步的汇总. 创建数据表 select * from emp_test (1) rollup单个字段 如按照country字段进行分组,并在最 ...
- oracle按照指定列分组合计group by rollup()
group by rollup() 按分组合计 select grouping(status),status,owner,object_type,count(*) from dba_objects w ...
- oracle GROUP BY rollup
1.ROW_NUMBER() OVER函数的基本用法用法 http://www.cnblogs.com/fxgachiever/archive/2010/09/15/1826792.html 2.De ...
- oracle group by rollup实现小计、合计
SQL合计汇总实现数据N+1条显示: 注意group by rollup((ename, job, empno))!!! select decode(grouping(ename) + groupin ...
- grouping sets,cube,rollup,grouping__id,group by
例1: hive -e" select type ,status ,count(1) from usr_info where pt='2015-09-14' group by type,st ...
随机推荐
- 个人写spark小测试
写脚本生成类似文件 java 代码 封装类 package day0327; import java.util.UUID; public class data { private String ip; ...
- VC6.0 如何显示代码行号
VC6.0是一款比较经典.稳定的功能强大的IDE,目前也有很多人在使用.但美中不足的是它不能像其他IDE那样显示行号.这里需要用到一个插件VC6LineNumberAddin, 下载地址:http:/ ...
- C++语言运算符的功能、优先级和结合性
优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -& ...
- BZOJ3638|CodeForces 280D k-Maximum Subsequence Sum
题目链接:戳我 一类典型模型.线段树模拟网络流+区间最大K段和. 因为不会写,所以参考了黄学长的博客.但是我觉得他说得不够详细,所以想好好地解释一下: 前置技能1:区间最大子段和 如果K=1的时候怎么 ...
- [AGC003F] Fraction of Fractal 矩阵快速幂
Description SnukeSnuke从他的母亲那里得到了生日礼物--一个网格.网格有HH行WW列.每个单元格都是黑色或白色.所有黑色单元格都是四联通的,也就是说,只做水平或垂直移动且只经过 ...
- Centos6和7的区别
1.init系统 Linux 操作系统的启动首先从 BIOS 开始,接下来进入 boot loader,由 bootloader 载入内核,进行内核初始化.内核初始化的最后一步就是启动 pid 为 1 ...
- BeginEditorCommand的原理
代码来源 :http://www.arch-pub.com/problem-about-CPropertyPage_10682271.html CWnd* pAcadWnd = CWnd::FromH ...
- python的数据结构分类,以及数字的处理函数,类型判断
python的数据结构分类: 数值型 int:python3中都是长整形,没有大小限制,受限内存区域的大小 float:只有双精度型 complex:实数和虚数部分都是浮点型,1+1.2J bool: ...
- UITouch笔记
UITouch是什么 表示在在屏幕上触摸事件,包括触摸的位置.大小.力度(3D touch).运动. 在一系列触摸事件中,UITouch都是同一个,但是不要retain某一个UITouch.如果要保存 ...
- nginx高性能WEB服务器系列之九--nginx运维故障日常解决方案
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...