mysql聚合函数rollup和cube
轉:https://blog.csdn.net/liuxiao723846/article/details/48970443
一、with rollup:
with rollup?通常和group by?語句一起使用,是根據維度在分組的結果集中進行聚合操作。——對group by的分組進行匯總。
?
假設用戶需要對N個緯度進行聚合查詢操作,普通的groupby語句需要N個查詢和N次group by操作。而rollup的有點是一次可以去的N次groupby的結果,這樣可以提高查詢效率,同時大大減少網絡的傳輸流量。
?
1、rollup演示:
?
1)創建表:
create?table?rollup(
orderid?int?not?null,
orderdate?date?not?null,
empid?int?not?null,
custid?varchar(10)?not?null,
qty?int?not?null,
primary key(orderid,orderdate));
?
2)插入數據:
insert?into?rollup?select?1,\'2010-01-02\',3,\'A\',10;
insert?into?rollup?select?2,\'2010-04-02\',2,\'B\',20;
insert?into?rollup?select?3,\'2010-05-02\',1,\'A\',30;
insert?into?rollup?select?4,\'2010-07-02\',3,\'D\',40;
insert?into?rollup?select?5,\'2011-01-02\',4,\'A\',20;
insert?into?rollup?select?6,\'2011-01-02\',3,\'B\',30;
insert?into?rollup?select?7,\'2011-01-02\',1,\'C\',40;
insert?into?rollup?select?8,\'2009-01-02\',2,\'A\',10;
insert?into?rollup?select?9,\'2009-01-02\',3,\'B\',20;
?
3)首先按照年份分組、統計銷量;然后在對年份這一個緯度進行聚合
select?year(orderdate)?year,?sum(qty)?sum??from?rollupgroup by yere(orderdate);
?
然后對年份進行聚合:
?
select?year(orderdate)?year,?sum(qty)?sum??from?rollup
group by yere(orderdate)?with rollup;
?
和普通的groupby差別不大,只是多了一個(null,220),表示對所有的year再做一次聚合,即訂單數量總和。對單個唯獨進行rollip操作只是可以在最后得到聚合的數據,對比groupby語句并沒有非常大的優勢。
?
4)對多個緯度進行聚合:
select?empid,custid,?year(orderdate)?year,sum(qty)?sum?from?rollup
group by empid,custid,year(orderdate)
with rollup;
?
?
對三次分組都進行了聚合,一個有三種聚合,其中:
- (null,null,null)表示最后的聚合
- (empid,null,null)表示僅對(empid)一列進行分組的聚合結果
- (empid,custid,null)表示對(empid,custid)兩列進行分組的聚合結果
- (empid,custid,year)表示對這3列進行分組的聚合結果——也就是group by本身聚集
?
所以,上面結果等價于:(未排序)
select?empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by empid,custid,year(orderdate)
union
select?empid,custid,null,sum(qty)?sum?from?rollup
group by empid,custid
union
select?empid,null,null,sum(qty)?sum?from?rollup
group by empid
union
select?null,null,null,sum(qty)?sum?from?rollup
?
?
2、rollup注意:
1)ORDER BY不能在rollup中使用,兩者為互斥關鍵字;
2)如果分組的列包含NULL值,那么rollup的結果可能不正確,因為在rollup中進行的分組統計時,null具有特殊意義。因此在進行rollup時可以先將
null轉換成一個不可能存在的值,或者沒有特別含義的值,比如:IFNULL(xxx,0)
3)mysql中沒有像oracle那樣的grouping()函數;
?
【實例】
selectifnull(dept,'總計') as '部門',ifnull(phone,'小計') as '電話',sum(money) as '金額' fromgroupTable group by?
??? dept,phone with rollup;
+--------+------+------+
?|?部門??|?電話|?金額|
??+--------+------+------+
?|?財務部| 6001 |?? 10 |
??|財務部| 6003 |? 100 |
??|財務部|?小計|? 110 |
??|營業部| 8001 |?? 20 |
??|營業部| 8002 |?? 30 |
?|?營業部|?小計|?? 50 |
?|?總計??|?小計|? 160 |
?+--------+------+------+
二、cube:
?
rollup是cube的一種特殊情況,和rollup一樣,cube也是一種對數據的聚合操作。但是rollup只在層次上對數據進行聚合,而cube對所有的維度進行聚合。具有N個維度的列,cube需要2的N次方次分組操作,而rollup只需要N次分組操作。
?
在mysql5.6.17版本中,只定義了cube,但是不支持cube操作。
?
2、rollup和cube的區別:
1)假設有n個維度,rollup會有n個聚合:
rollup(a,b)?? 統計列包含:(a,b)、(a)、()
rollup(a,b,c)統計列包含:(a,b,c)、(a,b)、(a)、()
……以此類推ing……
?
2)假設有n個緯度,cube會有2的n次方個聚合
cube(a,b)???? 統計列包含:(a,b)、(a)、(b)、()
cube(a,b,c)??統計列包含:(a,b,c)、(a,b)、(a,c)、(b,c)、(a)、(b)、(c)、()
……以此類推ing……
?
3、可以用rollup來模擬cube:
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by empid,custid,year(orderdate)
with rollup
union
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by empid,year(orderdate),custid
with rollup
union
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by custid,year(orderdate),empid
with rollup
union
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by custid,empid,year(orderdate)
with rollup
union
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by?year(orderdate),empid,custid
with rollup
union
select?
????empid,custid,year(orderdate)?year,sum(qty)?sum?from?rollup
group by?year(orderdate),empid,custid
with rollup;
總結
以上是生活随笔為你收集整理的mysql聚合函数rollup和cube的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 傲腾服务器系统,服务器装傲腾内存
- 下一篇: 某著名公司2015暑期实习招聘试题及相关