MySQL 基础 ———— 分组查询

引言

承接上一篇《MySQL 基础 ————高频函数总结》,本篇单独针对分组查询进行简单的总结和归纳,并为后续更为复杂的DQL 语句做好铺垫。

查询语句:

SELECT AVG(salary) FROM teacher;

实际上是以全表的 salary 字段来求平均值。但是在实际应用中往往有一些特殊的需求,比如,求每个部门的平均工资。这个时候就需要将表进行分组,然后再进行查询

上图左边的是 teacher 的整张表,我们通过 lesson (任课科目) 来进行分组,然后再求出每种科目老师的平均工资。

 一、GROUP BY 子句

使用 GROUP BY 子句进行数据的分组,能够分为一组的字段,值必须相同。

GROUP BY 子句的位置在 WHERE 查询条件之后,而且一般情况下,GROUP BY 都是处在查询语句偏后的位置。

注意,查询列表,必须出现在 分组函数GROUP BY 子句中。比如,引言中的按照学科分组,查询平均工资:

SELECT AVG(salary) FROM teacher GROUP BY lesson;

其中,查询列表就是 salary,因为每组中必有 >= 1 条记录,因此,只有进行聚合计算,才能使结果具有实际意义,因此,要么查询的字段可以放在分组函数中求出特定的值,要么就是该分组字段

二、案例分析

从案例中,可以总结出一定的规律,即当需求中有出现类似“每个”的字样,且这个字段与该表中记录的关系是一对多的话,就可能用到分组查询。

同时,根据上一节的结论,查询列表必须放在分组函数中,否则不具有意义。因此,我们可以得出,只要查询用到了 GROUP BY 子句,就一定会用到 分组函数

案例:有如下一张学生分数表,查询出语数外总分最高的分数:

SELECT MAX(chinese_score + math_score + english_score) 最高分 FROM score;

通过另一个SQL进行一下检查,可以看到结果完全正确:

SELECT chinese_score + math_score + english_score AS 总分,chinese_score 语文,math_score 数学,english_score 英语,stu_id 
FROMscore 
ORDER BY 总分 DESC ;

三、HAVING 子句

3.1 HAVING 子句介绍

在分组查询中,往往会涉及到需要先分组,后筛选的情况,与前面简单的先筛选后分组相区分。

比如有这样的需求,“查询 部门中人数  > 2 的部门”。很明显需要分两步来查询,第一步是先通过分组查询出所有部门的人数,如:

SELECT COUNT(*), dept_id
FROM emp
GROUP BY dept_id;

然后再在这个结果集中进行筛选,我们可以使用HAVING子句,在GROUP BY 子句后面再加一层筛选条件:

SELECT COUNT(*), dept_id
FROM emp
GROUP BY dept_id
HAVING COUNT(*) > 2;

另外,我们也可以通过另一种比较笨重的查询,子查询,结果是一样的:

SELECT m.人数,m.dept_id 
FROM(SELECT COUNT(*) 人数,dept_id FROMemp GROUP BY dept_id) m 
WHERE m.人数 > 3 ;

3.2 HAVING子句的使用时机

什么时候使用HAVING子句呢?

当然是在需要进行多步查询的时候,这时会出现一个明确的标志。我们知道,分组查询一定会用到分组函数,那么HAVING 子句的使用一定是由于分组函数上有筛选条件。

比如有这样的需求:查询部门最高工资 > 12000 的部门编号和最高工资。

思路是,首先最高工资是通过聚合函数算出,而在这个聚合函数的结果上又加了一个“ >12000 ” 的筛选条件,因此就会用到HAVING 子句。

思考:如何查询部门最高工资>12000的平均工资?且性能较好。

四、GROUP BY 子句扩展

4.1 按表达式结果分组

group by子句除了支持单个字段进行分组,还支持表达式分组。比如,按照学生名称的长度分组,查询每组学生的个数。

SELECT COUNT(*),CHAR_LENGTH(stu_name) 长度 
FROMstudent 
GROUP BY CHAR_LENGTH(stu_name) ;

另外,group by 后面支持别名,比如,上面的语句可以改成:

SELECT COUNT(*),CHAR_LENGTH(stu_name) 长度 
FROMstudent 
GROUP BY 长度 ;

4.2 多字段分组

GROUP BY 同样支持多字段分组,它的含义是在分组的基础上再进行分组。比如需求:先按照工种分组,再按照部门分组:

SELECT AVG(salary),department_id,job_id 
FROMemp 
GROUP BY job_id,department_id ;

多字段分组,只需要将各个字段用逗号隔开即可。不过,虽然说分组之上再分组,看似有前后顺序之分,但实际上,分组字段的前后字段不会影响最后结果,可以随意调换。

总结

基本非常重要的结论。

1、GROUP BY 子句一定在 WHERE 条件之后。

2、查询列表,必须出现在 分组函数GROUP BY 子句中。

3、当需求中“每个、每种” 后面的字段可能包含有多条记录的时候,就会用到分组查询,如,每个部门,每个年级,每种食品。

4、只要查询用到了 GROUP BY 子句,就一定会用到 分组函数

5、若逻辑上的筛选条件在分组之后,可以使用 HAVING 子句,对分组之后的数据进行过滤。

6、GROUP BY 子句支持表达式,支持别名,支持多字段分组,多字段分组用逗号隔开,字段顺序没有影响。

7、常见的分组函数有:COUNT()、AVG()、MAX() 、MIN() 等。

 

 综上,就是关于 分组相关的知识总结。欢迎文末留言和关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 基础 ———— 连接查询

引言 本篇文章承接《数据库与SQL语句》专栏,进入DQL的重要环节,可以说,这一部分的内容应该占据SQL语言的大部分使用场景。 本篇的连接查询知识,和后面的一些重要的查询知识总结,共同构成了在工作中80%的MySQL应用场景…

MySQL 基础 ———— 子查询

引言 承接《MySQL 基础 ———— 连接查询》,本文介绍和展示SQL中子查询的使用。 子查询是出现在其他语句中的select 语句,也称为内查询。外部的查询语句,称为主查询或外查询。 一、子查询的分类和支持的子句 按照子查询出现的位置&#…

MySQL 基础 ———— SQL语句的执行顺序与 LIMIT 子句

引言 到目前为止,已经总结了常见的SQL子句,包括 SELECT 、FROM、JOIN ... ON、WHERE、GROUP BY、HAVING、ORDER BY。 虽然SQL的书写顺序是固定的,但在MySQL引擎中执行的顺序并不完全和书写顺序一致。除了上述这些子句,下面将会介…

MySQL 基础———— UNION 联合查询

引言 联合查询与连接查询不同,通过UNION 关键字,我们可以将多个查询语句一同执行并将结果集展示出来,不涉及到任何关联关系。 UNION 的含义是“联合,并集,结合”,在MySQL中可以将多个查询语句的结果合并成…

MySQL 基础————常用数据类型

引言 从第一次学习mysql开始,不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海,对某些数据类型的定义和用法,也并不清晰,这篇文章,就好好总结一番,将MySQL中几个常用的数据类型归纳一下。 一、类…

MySQL 基础 ———— SAVEPOINT 的应用

引言 savepoint 关键字用于在数据库事务中设置一个存储点,在一个较长的事务中暂存数据,如果在事务末尾执行回滚,可选择性的回滚到 savepoint 设置的暂存点。 本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》,进一…

MySQL 基础 ———— 视图的应用与总结

引言 视图是一种虚拟表,和普通表的使用是一样的,视图的一大特点就是“临时性”,是通过表动态生成的数据,只保存SQL逻辑,不保存查询结果。 视图在实际生产中主要有两种应用场景: 1、多个地方用到同样的查…

MySQL 基础 ———— 变量

一、MySQL系统变量 系统变量是由系统提供,属于服务器层面。 系统变量分为:全局变量和会话变量。 全局变量一般要加 GLOBAL 关键字,例如在《MySQL 基础 ————事务与隔离级别总结》中提到的 GLOBAL TRANSACTION,就属于全局变量…

MySQL 基础 ———— 存储过程与函数

一、存储过程介绍 存储过程是一组预先编译好的SQL语句的集合,可理解成批处理语句。它的优点主要有以下几点: 1、提高代码的重用性; 2、简化操作; 3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率…

MySQL 基础 ———— 流程控制结构

引言 MySQL 中的流程控制作为基础知识的最后一块拼图,显得并不是特别重要,而且,在实际生产开发中,也往往不需要通过它来进行程序的控制,那么为什么还要学习它呢?我认为有以下几点: 1、知识的完…

MySQL 高级 ———— MySQL逻辑架构图简介

引言 本篇文章介绍MySQL的逻辑架构图。 MySQL并不完美,但足够灵活,能够适应高要求环境。MySQL不仅可以嵌入到应用程序中,同时也可以支持数据仓库、内容搜索、和部署软件、高可用的冗余系统、在线事务处理系统等各种应用类型。 一、MySQL逻…

Java正则表达式总结

引言 正则表达式(英文:regular expression)是用于描述字符串规则的工具,是记录文本规则的代码。 它可以用来搜索、编辑、处理文本。现有编程语言都支持正则表达式的处理,但每种语言都有细微的差别。 在Java 中&…

Linux 实操 —— Linux 系统性能分析

引言 最近配合解决压测(性能测试)方面的问题,了解到了一些可以监控 Linux 系统性能指标,如CPU、IO、内存等的工具。 此篇博客主要讲解 Linux 系统监控的一些重点内容以及 sar 命令的使用。 一、Linux 性能分析聚焦 Linux 性能…

Java 动态代理解析

引言 本博客总结自《Java 编程思想》第十四章 一、实现第一个动态代理程序 代理是软件设计中重要的设计思想,它允许我们在调用实际操作之前或之后解耦式地编写额外的操作,而一旦不需要这些操作了,就可以轻易的移除它们。 浏览了《编程思想…

MySQL 基础 ————高频函数总结

一、MySQL函数调用方式 函数调用的基本语法: SELECT 函数(实参列表) [FROM 表] 其中,对于函数,需要重点关注三点: 1、函数的名称 2、参数列表 3、函数功能 二、函数的分类 在 MySQL中,函数分为两类:1、…

MySQL 高级 —— 复合索引简介(多列索引)

引言 复合索引是指包含多个数据列的索引,与之概念相对的是单列索引,仅包含一个数据列。在大多数情况下,建立多列索引的好处都要多于单列索引。另外,复合索引最多支持16个列,但请一定不要让复合索引包含太多的列&#…

MySQL 高级 —— 索引实现的思考

引言 最近看了一个公开课,是有关MySQL对索引设计的思考。详细讲解了几种索引实现的设计思考与利弊辨析,讨论了为什么MySQL默认情况下会使用B树索引,B树索引又对B树做了哪些结构改进。 本片博客通过个人的学习理解和总结,由几种简…

Git 初学札记(十)—— Reset 回退的三种状态解析

引言 工作中经常会涉及到需要本地代码覆盖更新的操作。有时候可能是从远端git 上直接覆盖更新,或者是其他本地分支覆盖更新当前分支等等。这个时候就需要用到 reset 操作。 reset 操作分为三种类型:Soft、Mixed、Hard。今天我们就来说说这三种类型究竟…

MySQL 高级 —— 深入理解 InnoDB 与 MyISAM

引言 在文件系统中,MySQL将每个数据库(也可以称之为schema)保存为数据目录下的一个子目录。创建表时,MySQL会在数据库子目录下创建一个与表同名的.frm文件保存表的定义。因为MySQL使用文件系统的目录和文件来保存数据库和表的定义…

关于 OutOfMemoryError 的总结与解决方法

引言 本文总结自周志明的《深入理解Java虚拟机》第二章部分内容。 这部分内容,可以为后续性能调优方面的工作起到铺垫作用。 一、什么是 OutOfMemoryError OurOfMemory 简称“OOM”, 直译为“内存耗尽”或“内存溢出”,当然,并…