mysql有rollup函数,Mysql,Oracle使用rollup函数完成行列统计
时间 2014-02-25 00:05:38 ITeye-博客
昨天突然在 一篇博客中看到了Mysql也有rollup函数,原博文使用了rollup进行行列统计,原博文链接如下:
本博文主要是记录下mysql和oracle使用rollup函数进行行列统计,内容比较简单。
首先是mysql,建表测试:
CREATE TABLE `tmysql_test_hanglietongji` (
`id` int(11) NOT NULL,
`c1` char(2) COLLATE utf8_bin DEFAULT NULL,
`c2` char(2) COLLATE utf8_bin DEFAULT NULL,
`c3` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
INSERT INTO `tmysql_test_hanglietongji` VALUES (1, ‘A1‘, ‘B1‘, 9);
INSERT INTO `tmysql_test_hanglietongji` VALUES (2, ‘A2‘, ‘B1‘, 7);
INSERT INTO `tmysql_test_hanglietongji` VALUES (3, ‘A3‘, ‘B1‘, 4);
INSERT INTO `tmysql_test_hanglietongji` VALUES (4, ‘A4‘, ‘B1‘, 2);
INSERT INTO `tmysql_test_hanglietongji` VALUES (5, ‘A1‘, ‘B2‘, 2);
INSERT INTO `tmysql_test_hanglietongji` VALUES (6, ‘A2‘, ‘B2‘, 9);
INSERT INTO `tmysql_test_hanglietongji` VALUES (7, ‘A3‘, ‘B2‘, 8);
INSERT INTO `tmysql_test_hanglietongji` VALUES (8, ‘A4‘, ‘B2‘, 5);
INSERT INTO `tmysql_test_hanglietongji` VALUES (9, ‘A1‘, ‘B3‘, 1);
INSERT INTO `tmysql_test_hanglietongji` VALUES (10, ‘A2‘, ‘B3‘, 8);
INSERT INTO `tmysql_test_hanglietongji` VALUES (11, ‘A3‘, ‘B3‘, 8);
INSERT INTO `tmysql_test_hanglietongji` VALUES (12, ‘A4‘, ‘B3‘, 6);
INSERT INTO `tmysql_test_hanglietongji` VALUES (13, ‘A1‘, ‘B4‘, 8);
INSERT INTO `tmysql_test_hanglietongji` VALUES (14, ‘A2‘, ‘B4‘, 2);
INSERT INTO `tmysql_test_hanglietongji` VALUES (15, ‘A3‘, ‘B4‘, 6);
INSERT INTO `tmysql_test_hanglietongji` VALUES (16, ‘A4‘, ‘B4‘, 9);
INSERT INTO `tmysql_test_hanglietongji` VALUES (17, ‘A1‘, ‘B4‘, 3);
INSERT INTO `tmysql_test_hanglietongji` VALUES (18, ‘A2‘, ‘B4‘, 5);
INSERT INTO `tmysql_test_hanglietongji` VALUES (19, ‘A3‘, ‘B4‘, 2);
INSERT INTO `tmysql_test_hanglietongji` VALUES (20, ‘A4‘, ‘B4‘, 5);
要完成的效果如下:
最简单的是使用union,如下:
select ifnull(c1, ‘total‘) as ‘total‘,
sum(if(c2 = ‘B1‘, C3, 0)) AS B1,
sum(if(c2 = ‘B2‘, C3, 0)) AS B2,
sum(if(c2 = ‘B3‘, C3, 0)) AS B3,
sum(if(c2 = ‘B4‘, C3, 0)) AS B4,
SUM(C3) AS TOTAL
from tmysql_test_hanglietongji
group by C1
union
select ‘total‘ as ‘total‘,
sum(if(c2 = ‘B1‘, C3, 0)) AS B1,
sum(if(c2 = ‘B2‘, C3, 0)) AS B2,
sum(if(c2 = ‘B3‘, C3, 0)) AS B3,
sum(if(c2 = ‘B4‘, C3, 0)) AS B4,
SUM(C3) AS TOTAL
from tmysql_test_hanglietongji
order by 1
也可以使用with rollup函数。注意当使用 rollup时, 你不能同时使用 order by子句进行结果排序
select ifnull(c1, ‘total‘) ‘total‘,
sum(if(c2 = ‘B1‘, C3, 0)) AS B1,
sum(if(c2 = ‘B2‘, C3, 0)) AS B2,
sum(if(c2 = ‘B3‘, C3, 0)) AS B3,
sum(if(c2 = ‘B4‘, C3, 0)) AS B4,
SUM(C3) AS TOTAL
from tmysql_test_hanglietongji
group by C1 with rollup;
with rollup其实是第一个的简化。
也可以这样写:
SELECT IFNULL(c1, ‘total‘) AS total,
SUM(IF(c2 = ‘B1‘, c3, 0)) AS B1,
SUM(IF(c2 = ‘B2‘, c3, 0)) AS B2,
SUM(IF(c2 = ‘B3‘, c3, 0)) AS B3,
SUM(IF(c2 = ‘B4‘, c3, 0)) AS B4,
SUM(IF(c2 = ‘total‘, c3, 0)) AS total
FROM (SELECT c1, IFNULL(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1, c2 WITH ROLLUP
HAVING c1 IS NOT NULL) AS A
GROUP BY c1 WITH ROLLUP;
HAVING c1 IS NOT NULL条件主要是过滤掉对整个tmysql_test_hanglietongji 表求和的那一行,以上面的子查询为例:
SELECT c1, IFNULL(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1, c2 WITH ROLLUP
结果是:
相当于:
SELECT c1, IFNULL(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1, c2
union ALL
SELECT c1, ‘total‘ AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1
union ALL
SELECT NULL, ‘total‘ AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
结果是:
可以看出group by c1,c2 with rollup相当于group by c1,c2 union group by c1(c2替换为NULL) union (c1,c2全部替换为NULL)。
这里的替换规则参考了链接
原文是替换Oracle的rollup,在Mysql中也适用。
使用普通sql写法是:
SELECT IFNULL(c1, ‘total‘) AS total,
SUM(IF(c2 = ‘B1‘, c3, 0)) AS B1,
SUM(IF(c2 = ‘B2‘, c3, 0)) AS B2,
SUM(IF(c2 = ‘B3‘, c3, 0)) AS B3,
SUM(IF(c2 = ‘B4‘, c3, 0)) AS B4,
SUM(IF(c2 = ‘total‘, c3, 0)) AS total
FROM (SELECT c1, IFNULL(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1, c2
HAVING c1 IS NOT NULL
union
SELECT c1, ‘total‘ as c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
group by c1) A
group by c1
UNION
SELECT ‘total‘ as total,
SUM(IF(c2 = ‘B1‘, c3, 0)) AS B1,
SUM(IF(c2 = ‘B2‘, c3, 0)) AS B2,
SUM(IF(c2 = ‘B3‘, c3, 0)) AS B3,
SUM(IF(c2 = ‘B4‘, c3, 0)) AS B4,
SUM(IF(c2 = ‘total‘, c3, 0)) AS total
FROM (SELECT c1, IFNULL(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
GROUP BY c1, c2
HAVING c1 IS NOT NULL
union
SELECT c1, ‘total‘ as c2, SUM(c3) AS c3
FROM tmysql_test_hanglietongji
group by c1) A
少了一个是因为上面的having要求c1 is not null,所以替换c1为NULL就没有了。
下面看下oracle中怎么写,想要的效果如图:
首先建表。
create table TSQL_TEST_HANGLIETONGJI
(
ID NUMBER(4) not null,
C1 VARCHAR2(2),
C2 VARCHAR2(2),
C3 NUMBER(4)
)
;
alter table TSQL_TEST_HANGLIETONGJI
add primary key (ID);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (1, ‘A1‘, ‘B1‘, 9);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (2, ‘A2‘, ‘B1‘, 7);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (3, ‘A3‘, ‘B1‘, 4);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (4, ‘A4‘, ‘B1‘, 2);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (5, ‘A1‘, ‘B2‘, 2);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (6, ‘A2‘, ‘B2‘, 9);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (7, ‘A3‘, ‘B2‘, 8);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (8, ‘A4‘, ‘B2‘, 5);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (9, ‘A1‘, ‘B3‘, 1);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (10, ‘A2‘, ‘B3‘, 8);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (11, ‘A3‘, ‘B3‘, 8);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (12, ‘A4‘, ‘B3‘, 6);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (13, ‘A1‘, ‘B4‘, 8);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (14, ‘A2‘, ‘B4‘, 2);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (15, ‘A3‘, ‘B4‘, 6);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (16, ‘A4‘, ‘B4‘, 9);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (17, ‘A1‘, ‘B4‘, 3);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (18, ‘A2‘, ‘B4‘, 5);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (19, ‘A3‘, ‘B4‘, 2);
insert into TSQL_TEST_HANGLIETONGJI (ID, C1, C2, C3)
values (20, ‘A4‘, ‘B4‘, 5);
最简单的写法是:
select c1,
sum(decode(c2,‘B1‘, C3, 0)) AS B1,
sum(decode(c2 ,‘B2‘, C3, 0)) AS B2,
sum(decode(c2 ,‘B3‘, C3, 0)) AS B3,
sum(decode(c2 ,‘B4‘, C3, 0)) AS B4,
SUM(C3) AS TOTAL
from tsql_test_hanglietongji
group by C1
UNION
SELECT ‘TOTAL‘,
sum(decode(c2 ,‘B1‘, C3, 0)) AS B1,
sum(decode(c2 ,‘B2‘, C3, 0)) AS B2,
sum(decode(c2 ,‘B3‘, C3, 0)) AS B3,
sum(decode(c2 ,‘B4‘, C3, 0)) AS B4,
SUM(C3)
FROM tsql_test_hanglietongji
然后使用rollup函数简化。
SELECT nvl(c1, ‘total‘) AS total,
SUM(decode(c2, ‘B1‘, c3, 0)) AS B1,
SUM(decode(c2, ‘B2‘, c3, 0)) AS B2,
SUM(decode(c2, ‘B3‘, c3, 0)) AS B3,
SUM(decode(c2, ‘B4‘, c3, 0)) AS B4,
sum(c3) AS total
FROM tsql_test_hanglietongji
GROUP BY ROLLUP(c1)
也可以这么写:
SELECT nvl(c1, ‘total‘) AS total_c,
SUM(decode(c2, ‘B1‘, c3, 0)) AS B1,
SUM(decode(c2, ‘B2‘, c3, 0)) AS B2,
SUM(decode(c2, ‘B3‘, c3, 0)) AS B3,
SUM(decode(c2, ‘B4‘, c3, 0)) AS B4,
SUM(decode(c2, ‘total‘, c3, 0)) AS total_r
FROM (SELECT c1, nvl(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY ROLLUP(c1, c2)
HAVING c1 IS NOT NULL) A
GROUP BY ROLLUP(c1);
rollup和普通sql替换上面也说了,举个例子:
SELECT c1, nvl(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY ROLLUP(c1, c2)
效果是:
普通sql写法是:
SELECT c1, nvl(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1, c2
union all
SELECT c1, nvl(null, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1
union all
SELECT NULL, ‘total‘ AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
order by 1, 2
细心的朋友也许注意到了,第二个union all带了order by 1,2而上面的mysql没有带order by,这和mysql和oracle对NULL的默认排序规则有关。
使用普通sql重写rollup为:
SELECT nvl(c1, ‘total‘) AS total_c,
SUM(decode(c2, ‘B1‘, c3, 0)) AS B1,
SUM(decode(c2, ‘B2‘, c3, 0)) AS B2,
SUM(decode(c2, ‘B3‘, c3, 0)) AS B3,
SUM(decode(c2, ‘B4‘, c3, 0)) AS B4,
SUM(decode(c2, ‘total‘, c3, 0)) AS total_r
FROM (SELECT c1, nvl(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1, c2
HAVING c1 IS NOT NULL
union all
SELECT c1, nvl(null, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1
HAVING c1 IS NOT NULL) A
GROUP BY c1
union all
SELECT nvl(null, ‘total‘) AS total_c,
SUM(decode(c2, ‘B1‘, c3, 0)) AS B1,
SUM(decode(c2, ‘B2‘, c3, 0)) AS B2,
SUM(decode(c2, ‘B3‘, c3, 0)) AS B3,
SUM(decode(c2, ‘B4‘, c3, 0)) AS B4,
SUM(decode(c2, ‘total‘, c3, 0)) AS total_r
FROM (SELECT c1, nvl(c2, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1, c2
HAVING c1 IS NOT NULL
union all
SELECT c1, nvl(null, ‘total‘) AS c2, SUM(c3) AS c3
FROM tsql_test_hanglietongji
GROUP BY c1
HAVING c1 IS NOT NULL) A
order by 1
这里也排除了c1 is null的情况。
通过上面的对比,发现oracle和mysql的rollup非常相似,对rollup函数感兴趣的朋友请仔细搜索rollup学习。
到这里该结束了,有任何意见请留言,如文中sql有错误也请指出,谢谢。
时间: 11-20
mysql有rollup函数,Mysql,Oracle使用rollup函数完成行列统计相关推荐
- mysql rollup函数_Mysql,Oracle使用rollup函数完成行列统计
昨天突然在 一篇博客中看到了Mysql也有rollup函数,原博文使用了rollup进行行列统计,原博文链接如下: 本博文主要是记录下mysql和oracle使用rollup函数进行行列统计,内容比较 ...
- oracle中存在函数吗,Oracle中的函数
Oracle中的函数 1.单行函数也称标量函数,对于从表中查询的每一行,该函数都返回一个值.单行函数可用与select子句中,也可用于where子句中.单行函数大致分为: >.日期函数 > ...
- oracle函数 case,oracle的case函数和case控制结构 (摘)
oracle的case函数和case控制结构 =========================================================== 作者: zhouwf0726(ht ...
- oracle 的wecate函数,1.Oracle中decode()函数用法
1.Oracle中decode函数用法 含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下: IF 条件=值1 THEN RETURN(翻 ...
- oracle to_char函数格式,oracle 中to_char函数的用法
一.日期格式转换 to_char(date,'格式'); select to_date('2005-01-01 ','yyyy-MM-dd') from dual; select to_char(sy ...
- oracle+decode函数用法,oracle中decode函数用法
oracle中decode函数用法以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! DECODE函数相当于一条件语句(IF ...
- oracle lookup函数,关于Oracle过程,函数的经典例子及解析
存储过程在调用时,不管有无参数,都需要加(),存储过程为pro_test(); call pro_test(); exec pro_test(); 在调用时不加括号,如call pro_test;则会 ...
- oracle trunc函数 q,Oracle之trunc函数
2.trunc()函数处理number型数字 语法格式:trunc(number[,decimals]) 其中: number 待做截取处理的数值:decimals 指明需保留小数点后面的位数,可选项 ...
- php函数 nvl,Oracle中nvl()函数
通过查询获得某个字段的合计值,如果这个值位null将给出一个预设的默认值 select nvl(sum(t.dwxhl),1) from tb_jhde t where zyd 通过查询获得某个字段的 ...
- mysql中nvl_Mysql中类似于oracle中nvl()函数的ifnull()函数
IFNULL(expr1,expr2) 如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2.IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境. mysq ...
最新文章
- flash新闻图片轮转————c#+数据库解决
- 山寨一把QQ移动终端聊天框,网页版效果其实也很好的!
- Windows与Linux系统拷贝文件之pscp的使用
- select、poll、epoll 比较
- codeforces 118A-C语言解题报告
- 从0开始学习自动化测试框架cypress(二)DOM
- Mac OS X中AMPPS中MySQL的配置文件(my.cnf)的位置
- 破解“还原卡”技术方法
- H5案例分析和场景应用
- vscode 字体大小和行间距设置
- Oracle客户端使用
- 西安交大2021考研计算机专业复试分数线,西安交通大学2021年研究生复试分数线是多少...
- TFTLCD原理与驱动与指令介绍
- 【Excel】正态分布函数 NORM.DIST / 标准差STDEV.S、STDEV.P
- iPhoneX、iPhoneXS、iPhoneXR、iPhoneXSMax屏幕适配尺寸@media
- 训练YOLO v4模型时,xml格式转txt格式
- uva 12012 - Detection of Extraterrestrial(KMP)
- 硬件加速. 记得加入
- ubuntu20.04 火狐打开b站 视频空白 评论空白问题
- 亿级访问量下的新浪微博系统架构
热门文章
- 杭电数据结构课程实践-哈密顿图的判断
- grads插值_GrADs常用函数
- 游戏角色开始动起来了,真帅!【python 游戏实战 03】
- 储存卡怎么格式化为fat32_64g储存卡怎么格式化成fat32格式化
- load west0479 matlab,matlab矩阵详解 - Matlab 资料库 视频 教程 讲义 代码 - 数学建模社区-数学中国...
- MS coco数据集介绍及下载
- Java 大白话讲解设计模式之 -- 建造者(Builder)模式
- 3道js面试题引发的脑洞
- 计算材料学与第一性原理、分子动力学、蒙特卡洛计算方法
- python——基于Pandas读取asc文件并保存为csv格式