分组数据
假如说我们现在有以下数据:
表名称为products,其内容如下
其中prod_id 为产品id,vend_id为供应商的id,prod_name为产品名称,prod_price为产品价格,prod_desc为产品的具体介绍。
现在我们有个需求,要求返回每个供应商提供的产品数目,或者返回只提供单项产品的供应商所提供的的产品,亦或者只返回提供了10个以上产品的供应商。 要完成这个需求,就需要用到“分组”。
数据分组
数据分组,首先要做的就是 创建分组。
创建分组
要创建分组,可以使用GROUP BY子句建立。假如现在我们要返回每个供应商提供的产品的数量,可以使用以下语句: 输入:
SELECT vend_id ,COUNT(*) AS num_prods FROM products GROUP BY vend_id;
其中,COUNT(*) 表示返回具体产品的数量。GROUP BY 表示按照vend_id排序并分组数据。
输出结果为:
过滤分组
在创建分组之后,MySQL同时还允许我们过滤分组,按照我们自己的喜好来规定包括哪些分组,排除哪些分组。要实现这个功能,可以使用HAVING。
输入:
SELECT vend_id ,count(*) AS vends FROM products GROUP BY vend_id HAVING COUNT(*) >= 3;
解释:选择供应商的id(vend_id),按照他们提供的产品的类型进行分组。并选出其中的产品类型数量大于等于3的供应商的id并输出。
输出:
通过这里我们可以看到,供应商id为空的会被省略掉。
分辨WHERE 和 HAVING
HAVING 和 WHERE 其实是非常类似的。而他们之间最大的区别是HAVING可以过滤分组,而WHERE可以过滤行。 假设我们现在有一个需求,从表products里面抽取出prod_price价格在10以上的,然后再对其进行分组,抽取出数量大于2的分组。那么可以使用以下WHERE和HAVING结合的语句: 输入:
SELECT vend_id,count(*) AS num_prods
FROM products
WHERE prod_price >= 10
GROUP BY vend_id
HAVING COUNT(*) >=2;
输出结果:
SELECT 子句的顺序
| 子句 | 说明 | 是否必须使用 |
|---|---|---|
| SELECT | 要返回的列或表达式 | 是 |
| FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
| WHERE | 行级过滤 | 否 |
| GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
| HAVING | 组级过滤 | 否 |
| ORDER BY | 输出排序顺序 | 否 |
| LIMIT | 要检索的行数 | 否 |
子查询
子查询自MySQL4.1之后引入支持。
这里先简要介绍所使用的的数据表。
订单表orders
客户表customers:
订单物品表 orderitems:
利用子查询进行过滤
已知, orders表存储一行。各订单的物品存储在相关的 orderitems表中。 orders表不存储客户信息。它只存储客户的ID。实际的客户信息存储在customers表中。
那么现在,我们要列出订购了物品TNT2的所有客户,应该怎么做?
- 检索包含物品TNT2的所有订单的编号
- 检索前一步骤列出的订单编号的所有客户的ID
- 检索前一步骤返回的所有客户ID的客户信息
(未完待续)