Oracle Group by+rollup+cube 的应用
首先我们创建一个示例表:
Create table test_group
(v_name varchar2(4)
,v_size varchar2(4)
,v_color varchar2(4)
,n_num number(4)
);
--插入数据
insert into test_group
select '桌子','大','红',10 from dual union all
select '桌子','大','绿',10 from dual union all
select '桌子','小','红',20 from dual union all
select '桌子','小','绿',40 from dual union all
select '椅子','大','红',20 from dual union all
select '椅子','大','绿',30 from dual union all
select '椅子','小','红',50 from dual union all
select '椅子','小','绿',100 from dual;
commit;
数据如下:
|
V_NAME |
V_SIZE |
V_COLOR |
N_NUM |
|
桌子 |
大 |
红 |
10 |
|
桌子 |
大 |
绿 |
10 |
|
桌子 |
小 |
红 |
20 |
|
桌子 |
小 |
绿 |
40 |
|
椅子 |
大 |
红 |
20 |
|
椅子 |
大 |
绿 |
30 |
|
椅子 |
小 |
红 |
50 |
|
椅子 |
小 |
绿 |
100 |
最简单的分组(为了初学者)
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,v_size
|
V_NAME |
V_SIZE |
TOTAL_NUM |
|
椅子 |
大 |
50 |
|
桌子 |
小 |
60 |
|
椅子 |
小 |
150 |
|
桌子 |
大 |
20 |
使用rollup
rollup() 是group by()子句的一种扩展,可以为每个分组返回小计记录以及为所有分组返回总计记录
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by rollup(v_name,v_size)
| V_NAME | V_SIZE | TOTAL_NUM |
| 椅子 | 大 | 50 |
| 椅子 | 小 | 150 |
| 椅子 | 200 | |
| 桌子 | 大 | 20 |
| 桌子 | 小 | 60 |
| 桌子 | 80 | |
| 280 |
注意结果中
对各个型号,各个物品(不分颜色)进行统计,;
对各个物品(不分大小和颜色)进行统计(蓝色底纹的数据)
对所有物品(不分类别,大小和颜色)进行总数量统计(绿色底纹的数据)
如果我想要所有大的物品(不区分椅子还是桌子,也不区分颜色)统计数据怎么办?
可以将group by rollup(v_name,v_size)变为:group by rollup(v_size ,V_name)
那如果我即想要对所有物品类别进行统计还想要对大小进行统计怎么办?这时就需要用到cube
使用cube
cube() 也是group by()子句的一种扩展,可以返回每一个列组合的小计记录(就是所有的维度都会进行统计),同时在末尾加上总计记录.
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by cube(v_name,v_size)
|
V_NAME |
V_SIZE |
TOTAL_NUM |
|
280 |
||
|
大 |
70 |
|
|
小 |
210 |
|
|
椅子 |
200 |
|
|
椅子 |
大 |
50 |
|
椅子 |
小 |
150 |
|
桌子 |
80 |
|
|
桌子 |
大 |
20 |
|
桌子 |
小 |
60 |
注意结果中
对各个型号,各个物品(不分颜色)进行分别统计;
对各个物品(不分大小和颜色)进行分别统计(蓝色底纹的数据)
对各个型号(不分物品和颜色)进行分别统计(黄色底纹的数据)
对所有物品(不分类别,大小和颜色)进行统计(绿色底纹的数据)
那么,如何可以方便的区分结果中那个是小计,哪个是合计呢?这时需要用到grouping_id()
使用grouping_id()
grouping_id()函数可以接受一列或多列,返回grouping()位向量的十进制值
grouping()位向量的计算方法是将按照顺序对每一列调用grouping()函数的结果组合起来
以grouping_id(v_name,v_size)为例:
v_name ,v_size 位向量 grouping_id(v_name,v_size)
非空 非空 00 0
非空 空 01 1
空 非空 10 2
空 空 11 3
Select v_name,v_size,v_color,sum(n_num) as total_num,grouping_id(v_name,v_size,v_color) as grping_Id
From test_group
group by cube(v_name,v_size,v_color)
order by 1,2,3
|
V_NAME |
V_SIZE |
TOTAL_NUM |
GRPING_ID |
|
椅子 |
大 |
50 |
0 |
|
椅子 |
小 |
150 |
0 |
|
椅子 |
200 |
1 |
|
|
桌子 |
大 |
20 |
0 |
|
桌子 |
小 |
60 |
0 |
|
桌子 |
80 |
1 |
|
|
大 |
70 |
2 |
|
|
小 |
210 |
2 |
|
|
280 |
3 |
7.使用group_id()函数
使用group_Id()之前,我们先分析一下下面的查询结果:
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,rollup(v_name,v_size)
|
V_NAME |
V_SIZE |
TOTAL_NUM |
|
椅子 |
大 |
50 |
|
椅子 |
小 |
150 |
|
桌子 |
大 |
20 |
|
桌子 |
小 |
60 |
|
椅子 |
200 |
|
|
桌子 |
80 |
|
|
椅子 |
200 |
|
|
桌子 |
80 |
和group by rollup(v_name,v_size) 相比结果集中多了两组重复的数据,少了总计.
多出来的数据是怎么来的呢?期实是由总计演化而来的,演化的过程如下:
首先可以将语句
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,rollup(v_name,v_size)
进行分解:
Select v_name,v_size,sum(n_num) as total_num
From test_group
where v_name='椅子'
group by rollup(v_name,v_size)
Select v_name,v_size,sum(n_num) as total_num
From test_group
where v_name='桌子'
group by rollup(v_name,v_size)
因为这里只有’椅子’,’桌子’两种物品.
结果分别如下:
|
V_NAME |
V_SIZE |
TOTAL_NUM |
|
椅子 |
大 |
50 |
|
椅子 |
小 |
150 |
|
椅子 |
200 |
|
|
椅子 |
200 |
|
V_NAME |
V_SIZE |
TOTAL_NUM |
|
桌子 |
大 |
20 |
|
桌子 |
小 |
60 |
|
桌子 |
80 |
|
|
桌子 |
80 |
这是两个使用rollup的查询结果,里面的总计部分期初和小计部分的数据是相同的,因为只计也只是包含椅子(或桌子)的数据. 所以这里可以用椅子(或桌子)来填充总计的空白处(表格中的黄色字体部分).然后将这两个表格的数据合并在一起,就可以得到
group by v_name,rollup(v_name,v_size) 的结果了.
那我们如何来区分这两组相同的数据呢?这时就可以用到group_id()函数了.
如下:
Select v_name,v_size,sum(n_num) as total_num
,grouping_id(v_name,v_size) as gping_id
,group_Id() as gp_id
From test_group
group by v_name,rollup(v_name,v_size)
|
V_NAME |
V_SIZE |
TOTAL_NUM |
GPING_ID |
GP_ID |
|
椅子 |
大 |
50 |
0 |
0 |
|
椅子 |
小 |
150 |
0 |
0 |
|
桌子 |
大 |
20 |
0 |
0 |
|
桌子 |
小 |
60 |
0 |
0 |
|
椅子 |
200 |
1 |
0 |
|
|
桌子 |
80 |
1 |
0 |
|
|
椅子 |
200 |
1 |
1 |
|
|
桌子 |
80 |
1 |
1 |
为了进行区分这里一并加上了grouping_id,注意观察grouping_id()和group_Id()的区别.
Oracle Group by+rollup+cube 的应用的更多相关文章
- oracle group by中cube和rollup字句的使用方法及区别
oracle group by中rollup和cube的区别: Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是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 ...
- Oracle分析函数 — sum, rollup, cube, grouping用法
本文通过例子展示sum, rollup, cube, grouping的用法. //首先建score表 create table score( class nvarchar2(20), course ...
- 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 ...
- PLSQL_基础系列02_分组函数GROUP BY / ROLLUP / CUBE(案例)
2014-11-30 Created By BaoXinjian
- Oracle的聚合函数group by结合CUBE和ROLLUP的使用
转自:https://docs.oracle.com/cd/E11882_01/server.112/e25554/aggreg.htm#DWHSG8618 CUBE Syntax CUBE appe ...
- [Oracle] Group By 语句的扩展 - Rollup、Cube和Grouping Sets
常常写SQL语句的人应该知道Group by语句的主要使用方法是进行分类汇总,以下是一种它最常见的使用方法(依据部门.职位分别统计业绩): SELECT a.dname,b.job,SUM(b.sal ...
- GROUP BY中ROLLUP/CUBE/GROUPING/GROUPING SETS使用示例
oracle group by中rollup和cube的区别: Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句.CUBE ROLLUP 是用于统计数据的. 实验 ...
随机推荐
- 使用SSMS 2014将本地数据库迁移到Azure SQL Database
使用SQL Server Management Studio 2014将本地数据库迁移到Azure SQL Database的过程比较简单,在SSMS2014中,有一个任务选项为“将数据库部署到Win ...
- windows服务创建与管理
安装windows 服务 C:\Users\chensimin>cd \ C:\>cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 C:\W ...
- ld链接问题解决
http://stackoverflow.com/questions/480764/linux-error-while-loading-shared-libraries-cannot-open-sha ...
- Hierarchical Token Bucket
例子一: # tc qdisc add dev eth0 root handle 1: htb default 30 # tc class add dev eth0 parent 1: classid ...
- editplus 替换换行 excel 表格 拼装sql语句技巧
这样的数据 放到sql中的in 语句中的时候格式需要换行 加上‘,’这样的内容. 操作内容: 用editplus 进行操作.Ctrl+H 查找的地方输入 \n ,替换的地方填写 ',' ...
- 【NOIP2007】矩阵取数
因为傻逼写错高精度搞了一下午浪费好多时间,好想哭qaq 原题: 帅帅经常更同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij据为非负整数.游戏规则如下: 1. 每次取数时须从每 ...
- kuangbin_ShortPath D (POJ 3268)
本来在想 单源多点很好解决但是多源单点怎么解 然后我发现只要倒过来就可以了 把输入存下来然后 处理完dis1 重新init一次 倒着再输入一次 处理dis2 输出max(dis1[i] + dis2[ ...
- C/C++语言void及void指针深层探索(转)
转自:http://www.lanou3g.com/blog/sort/SelfiOS/page/78 1.概述 许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一 ...
- SpringMVC给外部资源加版本号避免缓存
一.属性文件:version.properties ->内容:version=201608 二.java代码 public class configVersion implements Ser ...
- java 动态代码生成。
http://stackoverflow.com/questions/2320404/creating-classes-dynamically-with-java https://zeroturnar ...