关于MySQL的WITH ROLLUP子句

MySql 码拜 6年前 (2016-02-09) 436次浏览
查看官方文档(http://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html),with rollup的作用基本明白了,但是官方文档这句话是什么意思?
ROLLUP has a more complex effect when there are multiple GROUP BY columns. In this case, each time there is a “break” (change in value) in any but the last grouping column, the query produces an extra super-aggregate summary row.
解决方案

20

引用

12.10.2. GROUP BY修改程序
GROUP BY子句允许一个将额外行添加到简略输出端 WITH ROLLUP 修饰符。这些行代表高层(或高聚集)简略操作。ROLLUP 因而允许你在多层分析的角度回答有关问询的问题。例如,它可以用来向OLAP (联机分析处理) 操作提供支持。
设想一个名为sales 的表具有年份、国家、产品及记录销售利润的利润列:
CREATE TABLE sales
(
year    INT NOT NULL,
country VARCHAR(20) NOT NULL,
product VARCHAR(32) NOT NULL,
profit  INT
);
可以使用这样的简单GROUP BY,每年对表的内容做一次总结:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+–+–+
| year | SUM(profit) |
+–+–+
| 2000 |        4525 |
| 2001 |        3010 |
+–+–+
这个输出结果显示了每年的总利润, 但假如你也想确定全部年份的总利润,你必须本人累加每年的单个值或运行一个加法询问。
或你可以使用 ROLLUP, 它能用一个问询提供双层分析。将一个 WITH ROLLUP修饰符添加到GROUP BY  语句,使询问产生另一行结果,该行显示了全部年份的总价值:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+–+–+
| year | SUM(profit) |
+–+–+
| 2000 |        4525 |
| 2001 |        3010 |
| NULL |        7535 |
+–+–+
总计高聚集行被年份列中的NULL值标出。

当有多重 GROUP BY 列时,ROLLUP产生的效果更加复杂。这时,每次在除了最后一个分类列之外的任何列出现一个 “break” (值的改变) ,则问讯会产生一个高聚集累计行。

例如,在没有 ROLLUP的情况下,一个以年、国家和产品为基础的关于 sales 表的一览表可能如下所示:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales
-> GROUP BY year, country, product;
+–+–+–+–+
| year | country | product    | SUM(profit) |
+–+–+–+–+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
| 2000 | USA     | Calculator |          75 |
| 2000 | USA     | Computer   |        1500 |
| 2001 | Finland | Phone      |          10 |
| 2001 | USA     | Calculator |          50 |
| 2001 | USA     | Computer   |        2700 |
| 2001 | USA     | TV         |         250 |
+–+–+–+–+
表示总值的输出结果仅位于年/国家/产品的分析级别。当添加了 ROLLUP后, 问询会产生一些额外的行:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales
-> GROUP BY year, country, product WITH ROLLUP;
+–+–+–+–+
| year | country | product    | SUM(profit) |
+–+–+–+–+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | Finland | NULL       |        1600 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
| 2000 | India   | NULL       |        1350 |
| 2000 | USA     | Calculator |          75 |
| 2000 | USA     | Computer   |        1500 |
| 2000 | USA     | NULL       |        1575 |
| 2000 | NULL    | NULL       |        4525 |
| 2001 | Finland | Phone      |          10 |
| 2001 | Finland | NULL       |          10 |
| 2001 | USA     | Calculator |          50 |
| 2001 | USA     | Computer   |        2700 |
| 2001 | USA     | TV         |         250 |
| 2001 | USA     | NULL       |        3000 |
| 2001 | NULL    | NULL       |        3010 |
| NULL | NULL    | NULL       |        7535 |
+–+–+–+–+
对于这个问询, 添加ROLLUP  子句使村输出结果包含了四层分析的简略信息,而不只是一个下面是怎么解释  ROLLUP输出:
•  一组给定的年份和国家的每组产品行后面, 会产生一个额外的总计行, 显示全部产品的总值。这些行将产品列设置为 NULL。
•  一组给定年份的行后面,会产生一个额外的总计行,显示全部国家和产品的总值。这些行将国家和产品列设置为  NULL。
• 最后, 在全部其它行后面,会产生一个额外的总计列,显示全部年份、国家及产品的总值。 这一行将年份、国家和产品列设置为 NULL。
使用ROLLUP  时的其它注意事项
以下各项列出了一些MySQL执行ROLLUP的特殊状态:
当你使用 ROLLUP时, 你不能同时使用 ORDER BY子句进行结果排序。换言之, ROLLUP 和ORDER BY 是互相排斥的。然而,你仍可以对排序进行一些控制。在 MySQL中, GROUP BY 可以对结果进行排序,而且你可以在GROUP BY列表指定的列中使用明确的 ASC和DESC关键词,从而对个别列进行排序。 (不论怎么样排序被ROLLUP添加的较高级别的总计行仍出现在它们被计算出的行后面)。
LIMIT可用来限制返回客户端的行数。LIMIT 用在 ROLLUP后面,  因此这个限制 会取消被ROLLUP添加的行。例如:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales
-> GROUP BY year, country, product WITH ROLLUP
-> LIMIT 5;
+–+–+–+–+
| year | country | product    | SUM(profit) |
+–+–+–+–+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | Finland | NULL       |        1600 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
+–+–+–+–+
将ROLLUP同 LIMIT一起使用可能会产生更加难以解释的结果,原因是对于理解高聚集行,你所掌握的上下文较少。
在每个高聚集行中的NULL  指示符会在该行被送至客户端时产生。服务器会查看最左边的改变值后面的GROUP BY子句指定的列。对于任何结果集合中的,有一个词匹配这些名字的列, 其值被设为 NULL。(若你使用列数字指定了分组列,则服务器会通过数字确定将哪个列设置为 NULL)。
由于在高聚集行中的 NULL值在问询处理阶段被放入结果集合中,你无法将它们在问询本身中作为NULL值检验。例如,你无法将 HAVING product IS NULL 添加到问询中,从而在输出结果中删去除了高聚集行以外的部分。
另一方面, NULL值在客户端不以 NULL 的形式出现, 因而可以使用任何MySQL客户端编程接口进行检验。

.

20

rollup关键字运用时要注意字段的顺序,对字段列表从左到右,进行分层级的汇总.
例如:
select v1,v2,sum(vv)
from tb
group by v1,v2 with rollup
那么产生的结果集里,会有2种汇总,第一种就是:
v1,v2,sum(vv)
第二种就是:
v1,null,sum(vv) 也就是单独对v1的 分组,然后汇总

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于MySQL的WITH ROLLUP子句
喜欢 (0)
[1034331897@qq.com]
分享 (0)