news 2026/6/14 10:31:12

SQL必会必知整理-11-分组数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL必会必知整理-11-分组数据
11.1 数据分组
  • SQL聚集函数可用来汇总数据。这使我们能够对行进行计数,计算和与平均数,获得最大和最小值而不用检索所有数据。
  • 但如果要返回每个供应商提供的产品数,或者返回只提供单项产品的供应商所提供的产品,或返回提供10个以上产品的供应商,这就是分组显身手的时候了。分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算。
11.2 创建分组
  • 分组是在SELECT语句的GROUP BY子句中建立的。
SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;
  • 上面的SELECT语句指定了两个列,vend_id包含产品供应商的IDnum_prods为计算字段(用COUNT(*)函数建立)。GROUP BY子句指示MySQL按vend_id排序并分组数据。这导致对每个vend_id而不是整个表计算num_prods一次。
  • GROUP BY子句指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集。
  • GROUP BY子句规定:
    • GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。
    • 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
    • GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。
    • 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY句中给出。
    • 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
    • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
  • 使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值。
SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id WITH ROLLUP;
11.3 过滤分组
  • 除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。
  • MySQL为此目的提供了另外的子句,那就是HAVING子句。HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING COUNT(*) >= 2;
  • 最后一行增加了HAVING子句,它筛选出COUNT(*) >=2(两个以上的订单)的那些分组。
  • 这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
SELECT vend_id,COUNT(*) AS num_prod FROM products WHERE prod_price >= 10 GROUP BY vend_id HAVING COUNT(*) >= 2;
  • WHERE子句过滤所有prod_price至少为10行。然后按vend_id分组数据,HAVING子句过滤计数为2或2以上的分组。
11.4 分组和排序
  • 虽然GROUP BYORDER BY经常完成相同的工作,但它们是非常不同的。
ORDER BY
GROUP BY
排序产生的输出
分组行。但输出可能不是分组的顺序
任意列都可以使用(甚至非选择的列也可以使用)
只可能使用选择列或表达式列,而且必须使用每个选择列表达式
不一定需要
如果与聚集函数一起使用列(或表达式),则必须使用
  • 我们经常发现用GROUP BY组的数据确实是以分组顺序输出的。但情况并不总是这样,它并不是SQL规范所要求的。
  • 因为你以某种方式分组数据(获得特定的分组聚集值),并不表示你需要以相同的方式排序输出。应该提供明确的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 ORDER BY ordertotal;
  • 在这个例子中,GROUP BY子句用来按订单号(order_num列)分组数据,以便SUM(*)函数能够返回总计订单价格。HAVING子句过滤数据,使得只返回总计订单价格大于等于50的订单。最后,用ORDERBY子句排序输出。
11.5 SELECT子句顺序
子句
说明
是否必须使用
SELECT
要返回的列或表达式
FROM
从中检索数据的表
仅在从表选择数据时使用
WHERE
行级过滤
GROUP BY
分组说明
仅在按组计算聚集时使用
HAVING
组级过滤
ORDER BY
输出排序顺序
LIMIT
要检索的行数
  • SELECT语句执行顺序 :开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->SELECT子句->ORDER BY子句->LIMIT子句->最终结果
  • 每个子句执行后都会产生一个中间结果,供接下来的子句使用,如果不存在某个子句,就跳过
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 13:20:01

Ansible(一)—— 自动化运维工具 Ansible:集中化管理服务器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、Ansible 概述和运行机制1.1 Ansible 概述1.2 Ansible 工作机制1.3 Ansible 角色 (Role)二、Ansible 环境安装部署2.1 环境规划2.2 安装步骤2.3 主机清单配置…

作者头像 李华
网站建设 2026/6/13 9:31:08

uniapp开发鸿蒙:常见问题与踩坑指南

uniapp开发鸿蒙:常见问题与踩坑指南 一、开发环境配置问题 1.1 HBuilderX无法识别鸿蒙设备 问题现象:在HBuilderX中运行到鸿蒙时,设备列表为空或无法识别真机。 解决方案: 确保DevEco Studio已正确安装并启动在DevEco Studio中新建…

作者头像 李华
网站建设 2026/6/10 2:00:35

人脑运行原理与现代操作系统

一、人脑运行原理(基于神经科学共识) 1. 结构基础 神经元网络:人脑约有860亿神经元,通过突触连接形成复杂网络。信息以电信号(动作电位)和化学信号(神经递质)传递。模块化与分布式处…

作者头像 李华
网站建设 2026/6/13 17:30:34

【毕业设计】基于springboot+微信小程序的智能医疗管理系统设计与实现(源码+文档+远程调试,全bao定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华