guangzhou

Recent posts:
Blog index
About
RSS

MySQL分组数据

July 03, 2017     MySQL   1,491   

本文将介绍如何分组数据,以便能汇总表内容的子集。这涉及两个新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包含产品供应商的ID,num_prods为计算字段(用COUNT(*)函数建立)。 GROUP BY子句指示MySQL按vend_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 BY和ORDER 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)