分组数据,以便于汇总表内容的子集 GROUP BY 和HAVING

数据分组

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

创建分组GROUP BY

通过GROUP BY创建分组,GROUP BY指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集。

SELECT
	vend_id,
	COUNT(*) AS num_prods 
FROM
	products 
GROUP BY
	vend_id;

上述SQL的意思是通过vend_id进行升序排序分组,计算每个不同的vend_id的行数,并当作产品供应商的现有产品字段。
image.png

注意

  • BROUP BY可以包含任意数目的列
  • GROUP BY嵌套了分组,数据将在最后规定的分组上进行汇总。即在建立分组时,指定的所有列都一起计算(不能从个别的列取回数据)
  • GROUP BY列出的每个列都必须是检索列或有效的表达式(聚集函数除外),不能使用别名
  • SELECT语句中的每个列都必须在GROUP BY子句中给出(聚集函数除外)
  • 如果分组中有NULL值,则将NULL作为一个分组返回,如果有多行NULL,其将分为一组
  • GROUP BY必须出现在WHERE之后和ORDER BY子句之前

过滤分组HAVING

除了分组数据外,MySQL可以过滤分组,规定包括哪些分组,派出哪些分组
WHERE过滤行,HAVING过滤分组。
所有类型的WHERE子句都可以用HVING来替代

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

上述SQL意为在orders表中查找订单数大于等于2个的cust_id过滤
image.png

HAVING和WHERE的区别

  • HAVING支持所有WHERE操作符
  • WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤
SELECT
	vend_id,
	COUNT(*) AS num_prods 
FROM
	products 
WHERE
	prod_price >= 10 
GROUP BY
	vend_id 
HAVING
	COUNT(*)>= 2;

同时使用WHERE和HAVING,返回具有2个及以上,价格为10及以上的产品的供应商
image.png

分组和排序

虽然GROUP BY和ORDER BY经常完成相同的工作,但是他们是非常不同的。

区别

  • ORDER BY
    排序产生的输出、任意列都可以使用
  • GROUP BY
    分组行、输出可能不是分组的数据、智能使用选择列或表达式列,而且必须使用每个选择列表达式

注意

在使用GROUP BY时,也要给出ORDER BY子句。这是保证数据正确排序的唯一方法。不要仅仅依赖GROUP BY排序数据

SELECT
	order_num,
	SUM( quantity * item_price ) AS ordertotal 
FROM
	orderitems 
GROUP BY
	order_num 
HAVING
	SUM( quantity * item_price )>= 50

查找订单总额大于等于50的订单,并根据订单号分组
image.png
如果要按照总金额大小进行排序可以如下

SELECT
	order_num,
	SUM( quantity * item_price ) AS ordertotal 
FROM
	orderitems 
GROUP BY
	order_num 
HAVING
	SUM( quantity * item_price )>= 50 
ORDER BY
	ordertotal;

image.png

SELECT子句顺序

SELECT子句顺序如下

  • SELECT
    需要检索返回的列、表达式
  • FROM
    检索数据的表
  • WHERE
    行级别过滤
  • GROUP BY
    分组说明
  • HAVING
    组级过滤
  • ORDER BY
    输出排序顺序
  • LIMIT
    要检索的行

这个家伙很懒,啥也没有留下😋