问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

MySQL rollup 函数?

发布网友 发布时间:2022-04-30 18:54

我来回答

2个回答

懂视网 时间:2022-04-30 23:15

原文  http://53873039oycg.iteye.com/blog/2021445 主题 MySQL Oracle数据库

    昨天突然在 一篇博客中看到了Mysql也有rollup函数,原博文使用了rollup进行行列统计,原博文链接如下:

    http://www.cnblogs.com/lhj588/archive/2012/06/15/2550392.html

    本博文主要是记录下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)。

   这里的替换规则参考了链接

   http://blog.itpub.net/519536/viewspace-610995

   原文是替换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有错误也请指出,谢谢。

 

Mysql,Oracle使用rollup函数完成行列统计

标签:

热心网友 时间:2022-04-30 20:23

oracle 中 rollup(A,(B,C
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
支付宝健康码变色规则 ...变绿码?昨天做了核酸检测结果是阴性,多久健康码从黄码变成绿码_百度... 母亲有乙肝孩子一定会有吗 ...的作文,600字,要有真实情感最好写心灵的。帮帮忙,必采纳。谢谢啦... ...自我介绍怎么写呀!,急急急!!!拜托各位谢谢啦!!_百度... 以“我身边的文明礼仪”为题写一篇作文,请各位大侠帮帮忙啦... 石家庄100平米房子改水电多少钱一平 石家庄居民水电煤气费都是多少钱? 石家庄水电一个月多少钱一个月多少钱 石家庄水电价格是多少钱 商业贷款未还清能用公积金贷款吗 小米插线板插上去就跳闸是什么情况 金钻怎么打发 一套商业贷款的房子(未还清)可以再贷公积金贷款吗 哪家移民英国的公司比较好? 有没有名人评价过香港? 张新伟的从业经历 已经读研究生了,还适合出国留学吗? 去澳洲留学读硕士,需要知道那些信息? 王健林跟房地产什么关系? 盖网独立董事Keith Bennett造访广州了吗? 英国留学读硕士怎样做到不挂科? 中国在哪方面取得了令人眼目的成绩? 出国读硕士,美国和加拿大哪个性价比更高一些?为什么? 出国留学读硕士研究生有年龄限制吗? 体检异常还能买保险吗 买保险要体检吗?对投保有哪些影响? 单位查体可以让家人查,影响本人以后买保险吗 奥克斯65中央空调机组一小时多少度电,房间三百多平方 身份卡借人检查身体,会不会影响买保险? 有未还清的商贷,可以用公积金贷款买房吗? 小米插线板经常跳闸,不可思议? 为什么我的插线板老是跳闸 小米石墨烯踢脚线取暖器点开28度不一会儿就跳闸了怎么回事儿_百度问一问 如何打发植物奶油,金钻的 插线板有问题会跳闸吗 为什么插座插上什么电器都跳闸,插座已经换过了,但是把插线板插上,插线板上的指示灯亮 看电视是什么意思? 公制M10*1.5*100指的是螺栓的什么规格? 我家的插座开关老是跳闸怎么回事啊 基本上每次打开插线板开关就跳闸(和电脑连接),保护开关有时推不上去,有时可以。是不是电脑的问题? M10 螺丝最长能有多长,螺杆长度在85mm左右的螺丝有哪些规格的, 家里插座的电源开关老是跳闸 冰箱如何储存干豆腐 我问女生你睡了吗她回我再看电视请问这是什么意思 DIY的台式机接到插线板上之后频繁导致漏电保护器跳闸是什么原因,该怎么办? 去别人家做客,他叫你去看电视是什么意思? 换了个大功率的插线板就跳闸 不换不跳 什么原因 手相前端与末端分别指手的什么地方 手指末端是哪儿