28-利用GROUP BY的WITH ROLLUP子句
在SQL语句中,使用GROUP BY的WITH ROLLUP字句可以检索出更多的分组聚合信息,它不仅仅能像一般的GROUP BY语句那样检索出各组的聚合信息,还能检索出本组类的整体聚合信息,具体如下例所示。
(1)在支付表payment中,按照支付时间payment_date的年月、经手员工编号staff_id列分组对支付金额amount列进行聚合计算如下:
mysql> select date_format(payment_date, '%Y-%m'), staff_id, sum(amount) from payment group by date_format(payment_date, '%Y-%m'), staff_id;
+------------------------------------+----------+-------------+
| date_format(payment_date, '%Y-%m') | staff_id | sum(amount) |
+------------------------------------+----------+-------------+
| 2005-05| 1 | 2621.83 |
| 2005-05| 2 | 2202.60 |
| 2005-06| 1 | 4776.36 |
| 2005-06| 2 | 4855.52 |
| 2005-07 | 1 | 14003.54 |
| 2005-07 | 2 | 14370.35 |
| 2005-08 | 1 | 11853.65 |
| 2005-08 | 2 | 12218.48 |
| 2006-02| 1 | 234.09 |
| 2006-02| 2 | 280.09 |
+------------------------------------+----------+-------------+
10 rows in set (0.06 sec)
mysql> select date_format(payment_date, '%Y-%m'), IFNULL(staff_id,''), sum(amount) from payment group by date_format(payment_date, '%Y-%m'), staff_id with rollup;
+------------------------------------+---------------------+-------------+
| date_format(payment_date, '%Y-%m') | IFNULL(staff_id,'') | sum(amount) |
+------------------------------------+---------------------+-------------+
| 2005-05 | 1| 2621.83 |
| 2005-05 | 2| 2202.60 |
| 2005-05 | | 4824.43 |
| 2005-06 | 1 | 4776.36 |
| 2005-06 | 2| 4855.52 |
| 2005-06|| 9631.88 |
| 2005-07 | 1|14003.54 |
| 2005-07 | 2|14370.35 |
| 2005-07 | | 28373.89 |
| 2005-08 | 1|11853.65 |
| 2005-08 | 2|12218.48 |
| 2005-08||24072.13 |
| 2006-02 | 1| 234.09 |
| 2006-02 | 2| 280.09 |
| 2006-02|| 514.18 |
| NULL | | 67416.51 |
+------------------------------------+---------------------+-------------+
16 rows in set (0.05 sec)
从上面的例子中可以看到第2个SQL语句的结果比第一个SQL语句的结果多出了很多行,而这些行反映出了更多的信息,例如,第2个SQL语句的结果的前2行表示2005-05月份各个员工(1、2)的经手的支付金额,而第3 行表示2005-05 月份总支付金额为4824.43,这个信息在第一个SQL语句中是不能反映出来的,第16行表示总支付金额为67416.51,这个信息在第一个SQL语句中是没有的。
其实WITH ROLLUP反映的是一种OLAP思想,也就是说这一个GROUP BY语句执行完成后可以满足用户想要得到的任何一个分组以及分组组合的聚合信息值。
注意:当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序。换言之,ROLLUP和ORDER BY是互相排斥的。此外,LIMIT用在ROLLUP后面。