在MySQL语句中,使用GROUP BY语句可以检索各组的聚合信息,添加WITH ROLLUP后能将分组后的信息按组聚合。
由下表进行数据测试:
1> 先试用不带聚合函数的GROUP BY语句进行测试得到结果如下图:
上图所测部分箭头所指右侧部分的数据是对应的,右侧部分方框中的数据是对上面该组数据的汇总,由于没有使用聚合函数,所以用NULL表示,最后一个是对所测所有查询结果的汇总。
2> 在GROUP BY中使用聚合函数进行测试,如下图所示:
上图所测部分箭头所指右侧部分的数据是对应的,右侧部分方框中的数据是对上面该组数据的汇总,由于使用了聚合函数SUM,所以对其上面每个分组求和,最后一个是对所测所有查询结果的汇总。
下图是一个产品销售收益表的汇总:
1> 在每一个最小分组(year/country/product)后会给出一个以year/country分组的数据汇总,该数据行中的product会被设置成NULL。
2> 在每个year/country小组后会给出一个以year分组的数据汇总,该数据行中country/product列都会被设置为NULL。
3> 最后一行是对所有数据的汇总,该数据行中year/country/product都被设置为NULL。
总结:WITH ROLLUP反应的是一种OLAP思想,也就是说一个GROUP BY语句执行完成后可以满足用户想要得到的任何一个分组以及分组组合的聚合信息值。
WITH ROLLUP中的NULL值是在每一个聚合行数据生成并发送到客户端时生成的。服务器会检测GROUP BY子句中最左侧改变值的列之后的列名并置为NULL(如果GROUP BY是通过列序号指定的,那么服务器会根据列位置进行判断并置NULL)。
因为超级聚合中的NULL值是在查询处理的最后阶段设置的,所以只能在SELECT列表或HAVING子句中使用这些NULL,但是不能在JOIN条件或者WHERE子句中通过使用NULL来筛选结果集。
注意:1> 在使用ROLLUP时,不能使用ORDER BY子句对结果进行排序,即ROLLUP与ORDER BY在MySQL中是互相排斥的。但是,仍然可以使用其他方式对排序进行控制。比如可以利用派生表将分组生成的数据作为中间结果,然后在使用ORDER BY进行排序。如下:
2> LIMIT可以用于限制返回客户端的数据行数,在ROLLUP后使用即可,它是对整个ROLLUP数据集基础上进行限制行数,需要注意的是这种使用方式可能会造成一些难以看懂的数据,因为对那些因为超级聚合产生的数据行没有一个清晰又明确的理解。
MySQL扩展实现了可以在SELECT列表中出现GROUP BY中没有的列名在这种情况下,服务器会自由的选取非聚合列的任意值放置在汇总的数据行中,在WITH ROLLUP中同样适用。