本文主要介绍,报表在使用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后的辅助函数的更多相关文章

  1. Oracle Group by+rollup+cube 的应用

    首先我们创建一个示例表: Create table test_group (v_name varchar2(4) ,v_size varchar2(4) ,v_color varchar2(4) ,n ...

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

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

  3. GROUP BY ROLLUP和CUBE 用法

    ROLLUP和CUBE 用法           Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是Group by  ROLLUP(A, B, C)的话 ...

  4. 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 ...

  5. Group By Rollup

    Rollup与group by组合使用,可对分组结果进行进一步的汇总. 创建数据表 select * from emp_test (1) rollup单个字段 如按照country字段进行分组,并在最 ...

  6. oracle按照指定列分组合计group by rollup()

    group by rollup() 按分组合计 select grouping(status),status,owner,object_type,count(*) from dba_objects w ...

  7. oracle GROUP BY rollup

    1.ROW_NUMBER() OVER函数的基本用法用法 http://www.cnblogs.com/fxgachiever/archive/2010/09/15/1826792.html 2.De ...

  8. oracle group by rollup实现小计、合计

    SQL合计汇总实现数据N+1条显示: 注意group by rollup((ename, job, empno))!!! select decode(grouping(ename) + groupin ...

  9. 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 ...

随机推荐

  1. CentOS7下搭建yum仓库

    服务端配置: 1.开启yum缓存 sed -i 's#keepcache=0#keepcache=1#g' /etc/yum.conf [root@control /]# cat /etc/yum.c ...

  2. 自己动手设计并实现一个linux嵌入式UI框架

    一直以来都是使用现成的UI框架,如微软的window.QT等,因为它有各种控件(如button.window.edit等)都已经封装实现好了.我们只要拿来用就是了,也一直认为它很神圣,没有深入了解它背 ...

  3. Windows上编译zlib

    把zlib 1.2.8解压到zlib/zlib-1.2.8 在deflate.c文件中把deflate_copyright改成一个static变量. 在zlib目录底下创建并用Visual Studi ...

  4. “全栈2019”Java第四十八章:重写方法Override

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. “全栈2019”Java第三十五章:面向对象

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. “全栈2019”Java第二十五章:流程控制语句中循环语句while

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. INSERT IGNORE 与INSERT INTO的区别,以及replace的用法

    INSERT IGNORE 与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在 的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据. 这样就可以保 ...

  8. 正则表达式 python

    下面这种方式 从结果上看 匹配的是关键字, 但是不是 每一次都可以 100% 准确 search_words_dict = { "肠炎宁": 0, "维生素AD" ...

  9. 条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》

    条目二十四<当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择> 当效率至关重要时,应该在map::operator[]和map::insert之 ...

  10. SQL语句之用户管理

    SQL语句系列 1.SQL语句之行操作 2.SQL语句之表操作 3.SQL语句之数据库操作 4.SQL语句之用户管理 占坑,待写……