工学1号馆

home

« | 返回首页 | »

MySQL分组数据

By Wu Yudong on July 03, 2017

本文将介绍如何分组数据,以便能汇总表内容的子集。这涉及两个新SELECT语句子句,分别是GROUP BY子句和HAVING子句。

分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算

1、创建分组

分组是在SELECT语句的GROUP BY子句中建立的。 先看一个例子:

mysql> select vend_id,count(*) as num_prods
-> from products
-> group by vend_id;

上面的SELECT语句指定了两个列, vend_id包含产品供应商的IDnum_prods为计算字段(用COUNT(*)函数建立)。 GROUP BY子句指示MySQLvend_id排序并分组数据。这导致对每个vend_id而不是整个表计算num_prods一次。

在具体使用GROUP BY子句前,需要知道一些重要的规定。
GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。

如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。

GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT 中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。

除聚集计算语句外, SELECT语句中的每个列都必须在GROUP BY子句中给出。

如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。

GROUP BY子句必须出现在WHERE子句之后, ORDER BY子句之前。

2、过滤分组

除了能用GROUP BY分组数据外, MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。

HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。

mysql> select cust_id,count(*) as orders
-> from orders
-> group by cust_id
-> having count(*)>=2;

3、分组和排序

虽然GROUP BYORDER BY经常完成相同的工作,但它们是非常不同的。下表汇总了它们之间的差别。

order by group by
排序产生的输出 分组行,但输出可能不是分组的顺序
任意列都可以使用 只可能使用选择列或表达式列,而且必须使用每个选择列表达式
不一定需要 如果与聚集函数一起使用列(或表达式),则必须使用

先看一个例子:

下面的SELECT语句类似于前面那些例子。它检索总计订单价格大于等于50的订单的订单号和总计订单价格:

mysql> select order_num,sum(quantity*item_price) as ordertotal
-> from orderitems
-> group by order_num
-> having sum(quantity*item_price)>=50;

为按总计订单价格排序输出,需要添加ORDER BY子句,如下所示:

mysql> select order_num,sum(quantity*item_price) as ordertotal
-> from orderitems
-> group by order_num
-> having sum(quantity*item_price)>=50
-> order by ordertotal;

4、select子句顺序

下表以在SELECT语句中使用时必须遵循的次序,列出迄今为止所学过的子句。

子句 说明 是否必须使用
select 要返回的列或表达式
from 从中检索数据的表 仅在从表选择数据时使用
where 行级过滤
group by 分组说明 仅在按组计算聚集时使用
having 组级过滤
order by 输出排序顺序
limit 要检索的行数

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)