时间 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函数完成行列统计相关推荐

  1. mysql rollup函数_Mysql,Oracle使用rollup函数完成行列统计

    昨天突然在 一篇博客中看到了Mysql也有rollup函数,原博文使用了rollup进行行列统计,原博文链接如下: 本博文主要是记录下mysql和oracle使用rollup函数进行行列统计,内容比较 ...

  2. oracle中存在函数吗,Oracle中的函数

    Oracle中的函数 1.单行函数也称标量函数,对于从表中查询的每一行,该函数都返回一个值.单行函数可用与select子句中,也可用于where子句中.单行函数大致分为: >.日期函数 > ...

  3. oracle函数 case,oracle的case函数和case控制结构 (摘)

    oracle的case函数和case控制结构 =========================================================== 作者: zhouwf0726(ht ...

  4. oracle 的wecate函数,1.Oracle中decode()函数用法

    1.Oracle中decode函数用法 含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下: IF 条件=值1 THEN RETURN(翻 ...

  5. oracle to_char函数格式,oracle 中to_char函数的用法

    一.日期格式转换 to_char(date,'格式'); select to_date('2005-01-01 ','yyyy-MM-dd') from dual; select to_char(sy ...

  6. oracle+decode函数用法,oracle中decode函数用法

    oracle中decode函数用法以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! DECODE函数相当于一条件语句(IF ...

  7. oracle lookup函数,关于Oracle过程,函数的经典例子及解析

    存储过程在调用时,不管有无参数,都需要加(),存储过程为pro_test(); call pro_test(); exec pro_test(); 在调用时不加括号,如call pro_test;则会 ...

  8. oracle trunc函数 q,Oracle之trunc函数

    2.trunc()函数处理number型数字 语法格式:trunc(number[,decimals]) 其中: number 待做截取处理的数值:decimals 指明需保留小数点后面的位数,可选项 ...

  9. php函数 nvl,Oracle中nvl()函数

    通过查询获得某个字段的合计值,如果这个值位null将给出一个预设的默认值 select nvl(sum(t.dwxhl),1) from tb_jhde t where zyd 通过查询获得某个字段的 ...

  10. mysql中nvl_Mysql中类似于oracle中nvl()函数的ifnull()函数

    IFNULL(expr1,expr2) 如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2.IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境. mysq ...

最新文章

  1. flash新闻图片轮转————c#+数据库解决
  2. 山寨一把QQ移动终端聊天框,网页版效果其实也很好的!
  3. Windows与Linux系统拷贝文件之pscp的使用
  4. select、poll、epoll 比较
  5. codeforces 118A-C语言解题报告
  6. 从0开始学习自动化测试框架cypress(二)DOM
  7. Mac OS X中AMPPS中MySQL的配置文件(my.cnf)的位置
  8. 破解“还原卡”技术方法
  9. H5案例分析和场景应用
  10. vscode 字体大小和行间距设置
  11. Oracle客户端使用
  12. 西安交大2021考研计算机专业复试分数线,西安交通大学2021年研究生复试分数线是多少...
  13. TFTLCD原理与驱动与指令介绍
  14. 【Excel】正态分布函数 NORM.DIST / 标准差STDEV.S、STDEV.P
  15. iPhoneX、iPhoneXS、iPhoneXR、iPhoneXSMax屏幕适配尺寸@media
  16. 训练YOLO v4模型时,xml格式转txt格式
  17. uva 12012 - Detection of Extraterrestrial(KMP)
  18. 硬件加速. 记得加入
  19. ubuntu20.04 火狐打开b站 视频空白 评论空白问题
  20. 亿级访问量下的新浪微博系统架构

热门文章

  1. 杭电数据结构课程实践-哈密顿图的判断
  2. grads插值_GrADs常用函数
  3. 游戏角色开始动起来了,真帅!【python 游戏实战 03】
  4. 储存卡怎么格式化为fat32_64g储存卡怎么格式化成fat32格式化
  5. load west0479 matlab,matlab矩阵详解 - Matlab 资料库 视频 教程 讲义 代码 - 数学建模社区-数学中国...
  6. MS coco数据集介绍及下载
  7. Java 大白话讲解设计模式之 -- 建造者(Builder)模式
  8. 3道js面试题引发的脑洞
  9. 计算材料学与第一性原理、分子动力学、蒙特卡洛计算方法
  10. python——基于Pandas读取asc文件并保存为csv格式