添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

举例:在产品表中,检索 每一个 供应商提供的商品的数量。

mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;
结果:

+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1001 |         3 |
|    1002 |         2 |
|    1003 |         7 |
|    1005 |         2 |
+---------+-----------+
4 rows in set (0.01 sec)

首先根据vend_id进行分组,然后对每一个分组在进行COUNT聚集。当检索的目的是针对每一个记录进行检索的时候,想到用GROUP BY,例如这里是针对每一个供应商。

GROUP BY的规定:

1、GROUP BY 后面可以包含多个列,这就是嵌套。

2、如果GROUP BY进行了嵌套,数据将在最后一个分组上进行汇总。

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

4、除了聚集语句外,SELECT语句中的每一个列都必须在GROUP BY子句中给出。

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

6、GROUP BY子句必须在WHERE 子句之后,ORDER BY 子句之前。

过滤分组结果

我们知道WHERE 子句用于过滤结果,但是对于分组的过滤WHERE子句不行。

因为WHERE子句,是针对行的过滤。要对分组结果进行过滤,必须使用HAVING子句,HAVING子句能针对分组的结果进行过滤。

在订单表中,检索出具有两个以上订单的客户id以及订单数量。

在这个检索需求中,需要先根据客户id进行分组,然后过滤出订单数量大于2的分组。

mysql> SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING orders>=2;
结果:

+---------+--------+
| cust_id | orders |
+---------+--------+
|   10001 |      2 |
+---------+--------+
1 row in set (0.00 sec)

与WHERE组合使用(先用WHERE过滤)

有的时候,GROUP BY和WHERE子句也要组合使用。比如:在产品表中检索出能提供2个以上商品,并且价格高于10的供应商。

首先,检索的是供应商,因此SELECT子句应该是SELECT vend_id

其次,产品表中,有价格这一列,因此对于价格高于10的条件的过滤要使用WHERE子句。SELECT vend_id FROM prodcuts WHERE prod_price>=10.

接着,对vend_id进行分组,这样就可以得到每个vend_id的价格高于10的商品数量,GROUP BY放到WHERE子句后。SELECT vend_id FROM prodcuts WHERE prod_price>=10 GROUP BY vend_id.

最后,对分组的结果过滤,过滤出2个以上商品的分组

mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price>=10 GROUP BY vend_id HAVING COUNT(*)>=2;
结果:

+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1003 |         4 |
|    1005 |         2 |
+---------+-----------+
2 rows in set (0.00 sec)

对分组结果进行排序

在订单明细表中,检索出订单总价格高于等于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 ordertotal;
结果是:

+-----------+------------+
| order_num | ordertotal |
+-----------+------------+
|     20006 |      55.00 |
|     20008 |     125.00 |
|     20005 |     149.87 |
|     20007 |    1000.00 |
+-----------+------------+
4 rows in set (0.08 sec)

SELECT 子句的顺序

SELECT

WHERE

GROUP BY

HAVING

ORDER BY

LIMIT

理解分组,可以这样:对GROUP BY子句后面跟随的列名进行分组,然后对每一个分组而不是整个表进行操作。举例:在产品表中,检索每一个供应商提供的商品的数量。mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;结果:+---------+-----------+| vend_id | n 2 索引扫描排序和文件排序(filesort)简介 我们知道InnoDB存储引擎以B+树作为索引的底层实现,B+树的叶子节点存储着所有 数据 页而内部节点不存放 数据 信息,并且所有叶子节点形成一个**(双向)链表**。 举个例...
可以。注意: where 肯定在 group by 之前。 一, group by 字句也和 where 条件语句结合在一起 使用 。当结合在一起时, where 在前, group by 在后。即先对select xx from xx的记录集合用 where 进行筛选,然后再 使用 group by 对筛选后的结果进行 分组 使用 having 字句对 分组 后的结果进行筛选。 二,需要注意 having where 的用法区别: having 只能用在 group by 之后,对 分组 后的结果进行筛选(即 使用 having 的前提条件是 分组 )。
having 的用法 having 字句可以让我们筛选成组后的各种 数据 where 字句在聚合前先筛选记录,也就是说作用在 group by having 字句前。而 having 子句在聚合后对组记录进行筛选。 SQL实例: 一、显示每个地区的总人口数和总面积. SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY regio...
-- CREATE TABLE label.t_order( -- id int not null AUTO_INCREMENT COMMENT '订单id', -- user_id bigint not null COMMENT '下单人id', -- user_name varchar(16) not null default '' COMMENT '用户名', -- price decimal(10, 2) not null default 0 COMMENT.
` GROUP BY ` 和 ` HAVING ` 都是 MySQL 数据 库中用于查询 数据 的子句。 ` GROUP BY ` 语句用于将查询结果按照一个或多个列 分组 ,以便进行聚合操作,如计算每组的总数、平均数等。例如,以下查询将按照 `department` 列 分组 并计算每组的平均工资: SELECT department, AVG(salary) FROM employees GROUP BY department; ` HAVING ` 语句用于筛选 分组 后的 数据 ,只返回满足特定条件的组。通常与 ` GROUP BY ` 一起 使用 。例如,以下查询将返回平均工资大于 5000 的部门: SELECT department, AVG(salary) FROM employees GROUP BY department HAVING AVG(salary) > 5000; 需要注意的是,` HAVING ` 子句中的条件应该基于聚合计算而非原始 数据 列。如果需要基于原始 数据 列进行筛选,则应该 使用 ` WHERE ` 子句。