title: mysql5.7與mysql8.0關於with rollup order by處理上的區別
date: 2019-10-23 16:39:09
tags:
需求:
常規問題,group by之后根據指定字段進行排序,如下根據c字段排序。
eg:select a,b,count(*) from tb_1 group by a,b with rollup order by c;
問題:
Q1:5.7就不支持with rollup 與 order by(distinct)一起用,這么優秀的功能,為啥不支持呢?
因為內部數據排序實在聚合計算之前,最后聚合列是直接被加在最后面的。並且5.7group by默認是排序的。如果從一開始就已經拍好順序了,那后面也就不會再排序或者去重,那自然也就無法支持自定義order by或者distinct操作了。
Q2:8.0.12開始支持,那8.0.12為啥能支持呢?以及最后出現的GROUPING函數是干啥的?
待研究,目測是SQL的執行順序變了吧
https://mysqlserverteam.com/mysql-8-0-grouping-function/
Q3:用一個例子說明支持后的使用效果吧
表結構如下:
root@test05:05:10>select * from t1;
+------+------+------+
| a | b | c |
+------+------+------+
| 111 | 11 | 11 |
| 222 | 22 | 22 |
| 111 | 12 | 12 |
| 222 | 23 | 23 |
+------+------+------+
5.7支持group by字段指定排序,而8.0是不支持的
5.7
root@test05:11:22>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a ASC , b DESC WITH ROLLUP;
+------+------+------+
| a | b | SUM |
+------+------+------+
| 111 | 12 | 12 |
| 111 | 11 | 11 |
| 111 | NULL | 23 |
| 222 | 23 | 23 |
| 222 | 22 | 22 |
| 222 | NULL | 45 |
| NULL | NULL | 68 |
+------+------+------+
7 rows in set (0.00 sec)
8.0
root@test05:13:09>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a ASC , b DESC WITH ROLLUP;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ASC , b DESC WITH ROLLUP' at line 1
5.7不支持order by,而8.0開始支持order by
5.7
root@test05:13:04>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a, b WITH ROLLUP ORDER BY a,b;
ERROR 1221 (HY000): Incorrect usage of CUBE/ROLLUP and ORDER BY
8.0
root@test05:13:13>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a, b WITH ROLLUP ORDER BY a,b;
+------+------+------+
| a | b | SUM |
+------+------+------+
| NULL | NULL | 68 |
| 111 | NULL | 23 |
| 111 | 11 | 11 |
| 111 | 12 | 12 |
| 222 | NULL | 45 |
| 222 | 22 | 22 |
| 222 | 23 | 23 |
+------+------+------+
7 rows in set (0.00 sec)
8.0支持order by任意列
5.7
root@test05:18:33>SELECT a, b, c, SUM(c) as SUM FROM t1 GROUP BY a, b WITH ROLLUP ORDER BY c desc;
ERROR 1221 (HY000): Incorrect usage of CUBE/ROLLUP and ORDER BY
8.0
root@test05:18:38>SELECT a, b, c, SUM(c) as SUM FROM t1 GROUP BY a, b WITH ROLLUP ORDER BY c;
+------+------+------+------+
| a | b | c | SUM |
+------+------+------+------+
| 111 | 11 | 11 | 11 |
| 111 | 12 | 12 | 12 |
| 111 | NULL | 12 | 23 |
| 222 | 22 | 22 | 22 |
| 222 | 23 | 23 | 23 |
| 222 | NULL | 23 | 45 |
| NULL | NULL | 23 | 68 |
+------+------+------+------+
8.0的GROUPING函數可以實現和5.7同樣的效果
5.7
root@test05:20:01>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a,b WITH ROLLUP;
+------+------+------+
| a | b | SUM |
+------+------+------+
| 111 | 11 | 11 |
| 111 | 12 | 12 |
| 111 | NULL | 23 |
| 222 | 22 | 22 |
| 222 | 23 | 23 |
| 222 | NULL | 45 |
| NULL | NULL | 68 |
+------+------+------+
7 rows in set (0.00 sec)
8.0
root@test05:19:38>SELECT a, b, SUM(c) as SUM FROM t1 GROUP BY a ,b WITH ROLLUP ORDER BY GROUPING(a), a, GROUPING(b), b;
+------+------+------+
| a | b | SUM |
+------+------+------+
| 111 | 11 | 11 |
| 111 | 12 | 12 |
| 111 | NULL | 23 |
| 222 | 22 | 22 |
| 222 | 23 | 23 |
| 222 | NULL | 45 |
| NULL | NULL | 68 |
+------+------+------+
7 rows in set (0.00 sec)
參考文檔:
https://mysqlserverteam.com/improvements-to-rollup-in-mysql/
