1 创建分组

  • 原数据表

SELECT vend_id,count(*) as num_prods
from products
GROUP BY vend_id;

mysql 分组后显示最后一条数据 mysql分组后再分组_select 子句及其顺序

2 group by

  • group by 子句可以包含任意数目的列。使得能对分组进行嵌套,为数据分组提供更加细致的控制;
  • 如果在 group by 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算,所以不能从个别的列取回数据;
  • group by 子句中列出的每个列都必须是检索列或者有效的表达式(不能是聚集函数)。如果 select 中使用表达式,则必须在 group by 子句中指定相同的表达式,不能使用别名;
  • 除聚集计算语句外,select 语句中的每个列都必须在 group by 子句中给出
  • 如果分组列中具有 NULL 值,则 NULL 将作为一个分组返回。如果列中有多行 NULL 值,它们将分为一组;
  • GROUP BY 子句必须出现在 where 子句之后,order by 子句之前;

2.1 聚集函数

mysql 分组后显示最后一条数据 mysql分组后再分组_select 子句及其顺序_02

2.2 with rollup

  • 可以的得到每个分组以及每个分组汇总级别(针对每个分组)的值
SELECT vend_id,count(*) as num_prods
from products
GROUP BY vend_id WITH ROLLUP;

mysql 分组后显示最后一条数据 mysql分组后再分组_mysql 分组后显示最后一条数据_03

3 过滤分组 having

  • where 过滤指定的是行而不是分组,它没有分组的概念;
  • 所有类型的 where 都可以用 having 来替代,区别就是 having 过滤分组;
  • having 支持所有 where 操作符;

  • 原数据表
SELECT cust_id,COUNT(*) as orders
from orders
GROUP BY cust_id
HAVING COUNT(*)>=2;

mysql 分组后显示最后一条数据 mysql分组后再分组_数据_04

3.1 havingwhere 的区别

  • where 在数据分组前进行过滤;
  • having 在数据分组后进行过滤;
  • where 排除的行不包括在分组中,这可能会改变计算值,从而影响 having 子句中基于这些值过滤掉的分组;

  • 原数据表

SELECT vend_id,COUNT(*) as num_prods
from products
WHERE prod_price >=10
GROUP BY vend_id;

mysql 分组后显示最后一条数据 mysql分组后再分组_select 子句及其顺序_05


SELECT vend_id,COUNT(*) as num_prods
from products
WHERE prod_price >=10
GROUP BY vend_id
HAVING count(*)>=2;

mysql 分组后显示最后一条数据 mysql分组后再分组_mysql 分组后显示最后一条数据_06


4 分组和排序

4.1 order bygroup by 区别

order by

group by

排序产生的输出

分组行,但是输出可能不是分组的顺序

任意列都可以使用(甚至非选择的列也可以使用)

只可能使用选择列或表达式列,而且必须使用每个选择列表达式

不一定需要

如果与聚集函数一起使用列(或表达式),则必须使用

4.2 不要忘记 order by

  • 一般在使用 group by 子句时,应该也给出 order by 子句,这是保证数据正确排序的唯一的方法,不要依赖 group by 排序数据

  • 原数据表
#检索总计订单价格大于等于50的订单的订单号和总计订单价格
SELECT order_num,SUM(quantity*item_price) as ordertotal
from orderitems
GROUP BY order_num
HAVING SUM(quantity*item_price)>=50;

mysql 分组后显示最后一条数据 mysql分组后再分组_group by_07


SELECT order_num,SUM(quantity*item_price) as ordertotal
from orderitems
GROUP BY order_num
HAVING SUM(quantity*item_price)>=50
order by ordertotal;

mysql 分组后显示最后一条数据 mysql分组后再分组_group by_08

5 select 子句及其顺序

子句

说明

是否必须使用

select

要返回的列或者表达式


from

从中检索的数据表

仅在从表选择数据时使用

where

行级过滤


group by

分组说明

仅在按组计算聚集时使用

having

组级过滤


order by

输出排序顺序


limit

要检索的行数