如何格式化MySQL中GROUP BY WITH ROLLUP的总计行?
更优实现方式:无需视图,用子查询或GROUPING()函数搞定
方法1:子查询替代视图
不用创建持久化视图,直接把ROLLUP的聚合逻辑塞进子查询,外层再处理RowType,逻辑和你用视图的方式一致,但不用维护两套独立语句:
SELECT IF(MyId IS NULL, 1, 0) AS RowType, MyId, Quantity FROM ( SELECT MyId, SUM(Quantity) AS Quantity FROM MyTable GROUP BY MyId WITH ROLLUP ) AS rolled_up_data;
方法2:用GROUPING()函数(更靠谱、更简洁)
MySQL专门给ROLLUP场景提供了GROUPING()函数,它能精准识别哪一行是ROLLUP生成的总计行:当列值是ROLLUP生成的NULL时返回1,其他情况(包括原表本身的NULL值)返回0,直接在单个查询里就能完成需求,连子查询都省了:
SELECT GROUPING(MyId) AS RowType, MyId, SUM(Quantity) AS Quantity FROM MyTable GROUP BY MyId WITH ROLLUP;
为啥原查询不行?
直接在GROUP BY WITH ROLLUP的SELECT里写IF(MyId IS NULL...)时,MySQL的执行逻辑会把原表中本来就为NULL的MyId行和ROLLUP生成的总计行混在一起判断,而且ROLLUP的NULL行是聚合后生成的,直接在同层判断会失效。子查询先把ROLLUP的结果算好,外层再判断就没问题;而GROUPING()是原生支持的ROLLUP判断工具,完全避开了这个问题。
内容的提问来源于stack exchange,提问作者Xaphann
相关产品推荐
相关产品推荐

