本文主要介绍,报表在使用group by rollup和group by cube后的辅助函数。

  1. CREATE TABLE TEST8
  2. (
  3. "ID" NUMBER,
  4. "ORDERID" NUMBER,
  5. "PRODUCTID" NUMBER,
  6. "PRICE" NUMBER(10,2),
  7. "QUANTITY" NUMBER
  8. )
  9. insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (1, 1, 1, 3, 10);
  10. insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (2, 1, 2, 4, 5);
  11. insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (3, 1, 3, 10, 2);
  12. insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (4, 2, 1, 3, 6);
  13. insert into TEST8 (ID, ORDERID, PRODUCTID, PRICE, QUANTITY) values (5, 2, 2, 4, 6);

基础数据

1、GROUPING函数

使用GROUPING函数处理汇总结果(在使用group by rollup和group by cube后的结果集)中的空值。

  1. select orderid,productid,count(orderid) ordercount from test8 group by cube(orderid,productid) order by orderid;

结果集按照orderid和productid进行汇总之后,出现了很多的空值,具体原因参考哥前面的随笔 ,so,必须解决这个问题,因为null值对报表结果来说没什么用,我们大致都会用0,'空','NULL'之类,来表示空值,所以GROUPING函数就是来干这个的.看代码:

  1. 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值修改为任何字段名类型的值了,代码如下:

  1. 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解决方法:

  1. select orderid,productid,count(orderid) from test8 group by (orderid,productid) order by orderid

(2)group by grouping sets解决方案

这边因为不知道他的功能,那么就直接上代码猜:

a、猜想一:grouping sets(orderid,productid)

  1. 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的合集,

下面验证猜想:

  1. select orderid,null productid,count(orderid) ordercount from test8 group by(orderid)
  2. union
  3. 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)

  1. 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的集合

  1. GROUP BY GROUPING SETS (A,B,C) 等价与 GROUP BY A
  2. UNION ALL
  3. GROUP BY B
  4. UNION ALL
  5. GROUP BY C

注意:grouping sets的特殊用法,grouping sets内部的最小单位是单个字段,其次是一个多个字段的几个用(字段1,字段2,......)表示,但是不支持嵌套括号,也没有必要,因为大多数情况下的报表都是2维的。

  1. GROUP BY GROUPING SETS ((A,B,C)) 等价与 GROUP BY A,B,C
  2.  
  3. GROUP BY GROUPING SETS (A,(B,C)) 等价与 GROUP BY A
  4. UNION ALL
  5. GROUP BY B,C

我们还可以混合使用,如下:

  1. GROUP BY A 等价于 GROUP BY A
  2. ,B ,B
  3. ,GROUPING SETS ((B,C)) ,C
  4.  
  5. GROUP BY A 等价于 GROUP BY A,B,C
  6. ,B UNION ALL
  7. ,GROUPING SETS (B,C) GROUP BY A,B
  8.  
  9. GROUP BY A 等价于 GROUP BY A,B,C
  10. ,B UNION ALL
  11. ,C GROUP BY A,B,C
  12. ,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或者它们中组合使用到同一列的情况,那么就会出现重复的数据行,代码如下:

  1. 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语句中的某一个存在的语句中可以使用,在其他语句中不能使用,代码如下:

  1. select orderid,productid,GROUP_ID(),count(orderid) ordercount from test8 group by orderid,rollup(orderid,productid)

GROUP_ID()方法显示红框内的两条数据重复出现了一次,那么这两条数据就需要过滤

b、下面使用HAVING(相当于where,但是having只能用于分组函数的数据过滤,只能用于包含group by的语句中) 来过滤重复的数据,代码如下:

  1. 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. 风尘浪子 只要肯努力,梦想总有一天会实现 WF工作流与Web服务的相互调用 —— 通过Web服务调用Workflow工作流(开发持久化工作流) _转

    如果你曾经负责开发企业ERP系统或者OA系统,工作流对你来说一定并不陌生.工作流(Workflow)是对工作流程及其各操作步骤之间业务规则 的抽象.概括.描述.工作流要解决的主要问题是:为实现某个业务 ...

  2. Tomcat应用配置

    为Tomcat添加管理员 为了更好的管理tomcat服务器,我们通常会给tomcat添加用户管理员,这样就可以登录进入查看发布的项目.以下是实际操作步骤: 在Tomcat的配置目录下找到tomcat- ...

  3. [LeetCode 题解]: Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  4. Tomcat负载均衡原理详解及配置(Apache2.2.19+Tomcat7.0.12)

    结构图 JAVA项目一般直接用Tomcat作为Web服务器.为了增加tomcat的性能和稳定性,我们一般采用balance和session同步机制. 下图列出了我们常用也是最简单的解决方案. 说明 1 ...

  5. onbeforeunload事件

    window.onbeforeunload=function(){ return "您正在编辑的博客尚未保存,确定要离开此页吗?"; }; 1.这个事件存在的意义就是防止用户不小心 ...

  6. python字符串的切片

    # 字符串的切片 """ (5)字符串的切片 :切片就是截取字符串的意思 (1)语法 =>字符串[::] 完整格式:[开始索引:结束索引:间隔值 (2)[:结束索引 ...

  7. CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

    题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\ ...

  8. ubuntu下搭建Discuz

      环境:我用桥接方式创建了一个ubuntu16的虚拟机,ip为192.168.0.220   1.安装mysql sudo apt-get install mysql-server mysql-cl ...

  9. 性能测试—认识JMeter(一)

     性能测试—认识JMeter(一) <零成本web性能测试>第二章 JMeter基础知识总结和自己的理解 一.JMeter百度词条概念 Apache JMeter是Apache组织开发的基 ...

  10. spring里面的ioc的理解?

    spring里面的ioc就是控制反转,其实现核心是DI(依赖注入),控制反转不向以前java代码里面,通过new关键字来实现创建对象,这样每段代码之间的耦合度就比较高,为了降低每个小模块之间的耦合度, ...