MySQL:GROUP BY 分组查询

分组查询是SQL中一个非常强大的功能,它允许我们将数据按照一个或多个字段进行分组,并对每个分组进行聚合计算(如求和、平均值、最大值、最小值等)。在MySQL中,我们使用 GROUP BY 关键字来实现分组查询。

核心语法

SELECT column_1, column_2, ..., AGGREGATE_FUNCTION(column_N)  
FROM table_name  
WHERE condition  
GROUP BY column_1, column_2, ...  
HAVING condition  
ORDER BY column_A;
  • SELECT 子句:选择需要显示的列,可以是普通列名,也可以是聚合函数的结果。
  • FROM 子句:指定查询的表名。
  • WHERE 子句(可选):在分组前对记录进行筛选。
  • GROUP BY 子句:指定分组的列名,MySQL会按照这些列的值将记录分组。
  • HAVING 子句(可选):在分组后对分组结果进行筛选。注意,HAVING通常与聚合函数一起使用,因为WHERE子句无法直接对聚合函数的结果进行筛选。
  • ORDER BY 子句(可选):对查询结果进行排序。
执行顺序

MySQL 会在 FROMWHERE 语句之后,HAVING, SELECT, DISTINCT, ORDER BYLIMIT 子句之前执行 GROUP BY :
在这里插入图片描述

单独使用 GROUP BY

单独使用 GROUP BY 关键字时,查询结果会只显示每个分组的第一条记录,相当于 DISTINCTDISTINCT 相当于一种特殊的分组查询。

DISTINCT 不同的是,GROUP BY对结果进行排序,而 DISTINCT 不会。如果二者一同使用,查询结果会进行排序。

MySQL 8.0删除了GROUP BY子句的隐式排序。因此,如果使用MySQL 8.0+,会发现上面使用GROUP BY子句查询的结果集没有排序。

GROUP 和 GROUP_CONCAT() 函数

GROUP BY 关键字可以和 GROUP_CONCAT() 函数一起使用。GROUP_CONCAT() 函数会把每个分组的字段值都显示出来

SELECT sex, GROUP_CONCAT(name) 
FROM student
GROUP BY sex;
'''
+------+----------------------------+
| sex  | GROUP_CONCAT(name)         |
+------+----------------------------+
| 女   | Henry,Jim,John,Thomas,Tom  |
| 男   | Dany,Green,Jane,Lily,Susan |
+------+----------------------------+
'''

多个字段分组查询时,会先按照第一个字段进行分组。如果第一个字段中有相同的值,MySQL 才会按照第二个字段进行分组。

SELECT age,sex GROUP_CONCAT(name)
FROM student
GROUP BY age,sex;
'''
+------+------+--------------------+
| age  | sex  | GROUP_CONCAT(name) |
+------+------+--------------------+
|   21 | 女   | John               |
|   22 | 女   | Thomas             |
|   22 | 男   | Jane,Lily          |
|   23 | 女   | Henry,Tom          |
|   23 | 男   | Green,Susan        |
|   24 | 女   | Jim                |
|   25 | 男   | Dany               |
+------+------+--------------------+
'''

如果第一个字段中的数据都是唯一的,那么 MySQL将不再对第二个字段进行分组。

GROUP 和 聚合函数 aggregate_function()

在数据统计时,GROUP BY 关键字经常和 聚合函数 一起使用。

聚合函数包括 COUNT()SUM()AVG()MAX()MIN()

  • COUNT() 用来统计记录的条数
  • SUM() 用来计算字段值的总和
  • AVG() 用来计算字段值的平均值
  • MAX() 用来查询字段的最大值
  • MIN() 用来查询字段的最小值。
SELECT col, aggregate_func(parameters) [AS alias] 
FROM table_name
GROUP BY col;

如下的查询会按照 department_id 对 employees 表中的记录进行分组,并计算每个部门的平均薪资。

SELECT department_id, AVG(salary) AS avg_salary  
FROM employees  
GROUP BY department_id;
GROUP BY 和 表达式

除了对列分组查询之外,也可以借助表达式对行进行分组,允许我们对数据进行更复杂的分组逻辑:

SELECT expression FROM table_name
GROUP BY expression;
  • 需要注意的是:GROUP BY 中的表达式要和 SELECT 中的相同

如下的查询按员工的入职年份进行分组,并计算每年入职的员工数。

SELECT YEAR(hire_date) AS hire_year, COUNT(*) AS hires_per_year  
FROM employees  
GROUP BY YEAR(hire_date);
MySQL 和 SQL 标准下的 GROUP BY
  • 别名使用:MySQL 允许在 GROUP BY 子句中直接使用 SELECT 列表中的别名,而SQL标准通常不允许这样做,要求直接使用列名或表达式。

  • 排序:虽然 GROUP BY 本身不直接指定排序,但结果集可以通过 ORDER BY 进行排序。MySQL允许在 GROUP BY 后直接跟 ASCDESC (这不是标准SQL的做法,且因MySQL版本而异),更标准的做法是在整个查询的末尾使用 ORDER BY

HAVING 过滤分组

在MySQL中,使用 HAVING 关键字对分组后的数据进行条件筛选,通常与 ORDER BY 一同使用。

语法结构:

SELECT column_ FROM table_name
[ORDER BY column_]
HAVING condition_;

MySQL 会在 FROM, WHERE, SELECTGROUP BY 语句之后,ORDER BYLIMIT 语句之前执行 HAVING 子句:

在这里插入图片描述

HAVING 与 WHERE 的异同

HAVING 关键字和 WHERE 关键字都可以用来过滤数据,且 HAVING 支持 WHERE 关键字中所有的操作符和语法

  • 一般情况下,WHERE 用于过滤数据行,而 HAVING 用于过滤分组

  • WHERE 查询条件中不可以使用聚合函数,而 HAVING 查询条件中可以使用聚合函数

  • WHERE 在数据分组前进行过滤,而 HAVING 在数据分组后进行过滤 。

  • WHERE 针对数据库文件进行过滤,而 HAVING 针对查询结果进行过滤。
    也就是说,WHERE 根据数据表中的字段直接进行过滤,而 HAVING 根据前面已经查询出的字段进行过滤

SELECT name, sex FROM student WHERE height>180;
'''可以正常输出'''SELECT name, sex FROM student HAVING height>180;
'''
报错
ERROR 1054 (42S22): Unknown column 'height' in 'having clause'
'''
  • WHERE 查询条件中不可以使用字段别名,而 HAVING 查询条件中可以使用字段别名

分组查询案例

1. 查询每个部门的平均工资
SELECT AVG(salary), department_id  
FROM employees  
GROUP BY department_id;

这个查询将employees表中的数据按照department_id分组,并计算每个部门的平均工资。

2. 查询每个工种的最高工资
SELECT MAX(salary), job_id  
FROM employees  
GROUP BY job_id;

这个查询将employees表中的数据按照job_id分组,并计算每个工种的最高工资。

3. 添加筛选条件

查询邮箱中包含’a’字符的、每个部门的平均工资:

SELECT AVG(salary), department_id  
FROM employees  
WHERE email LIKE '%a%'  
GROUP BY department_id;

这个查询在分组前添加了筛选条件,只选择邮箱中包含’a’字符的记录进行分组和计算。

4. 复杂筛选条件

查询哪个部门的员工个数大于2:

SELECT COUNT(*), department_id  
FROM employees  
GROUP BY department_id  
HAVING COUNT(*) > 2;

这个查询首先按照 department_id 分组,然后计算每个部门的员工个数,最后通过HAVING子句筛选出员工个数大于2的部门。

5. 按表达式或函数分组

按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的组:

SELECT COUNT(*) AS c, LENGTH(last_name) AS len_name  
FROM employees  
GROUP BY LENGTH(last_name)  
HAVING c > 5;

这个查询按照员工姓名的长度进行分组,并计算每个长度组的员工个数,最后筛选出员工个数大于5的组。

6. 按多个字段分组

查询每个部门每个工种的员工平均工资:

SELECT AVG(salary), department_id, job_id  
FROM employees  
GROUP BY department_id, job_id;

这个查询同时按照 department_idjob_id 两个字段进行分组,并计算每个部门每个工种的员工平均工资。

注意事项

  1. 分组函数做条件:分组函数(如SUM()AVG()MAX()MIN()COUNT())做条件时,必须放在HAVING子句中,而不能放在WHERE子句中。
  2. 分组列的限制GROUP BY子句列出的每个列都必须是检索列或有效的表达式,但不能是聚合函数。
  3. NULL值的处理:如果分组列中包含NULL值,则NULL将作为一个单独的分组返回。

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

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

相关文章

Vue3自研开源Tree组件:人性化的拖拽API设计

针对Element Plus Tree组件拖拽功能API用的麻烦,小卷开发了一个API使用简单的JuanTree组件。拖拽功能用起来非常简单! 文章目录 使用示例allowDragallowDrop支持节点勾选支持dirty检测后台API交互 源码实现 使用示例 组件的使用很简单: 通过…

4.1.2、操作系统-概述及进程管理-状态管理和前趋图

进出的组成和状态 进程是计算机中正在运行的程序的实例。它是操作系统进行资源分配和管理的基本单位,包括代码、数据和执行状态等信息。 进程的组成:进程控制块PCB(唯一标志)、程序(描述进程要做什么)、数据(存放进程执行时所需数据)。 我们电脑中的QQ影音和网易云音乐可以并…

小米手机怎么查看电池剩余容量

最近发现自己的小米11pro的待机时间越来越短了,怀疑是电池剩余容量太小了,希望测下电池剩余容量好打算是否要更换下电池。 1.抓取bug测试 首先打开拨号界面,输入*#*#284#*#*然后开始抓取日志。 等待bug报告生成完毕,然后点击就…

Git原理与用法系统总结

目录 Reference前言版本控制系统Git的诞生配置Git配置用户名和邮件配置颜色配置.gitignore文件 Git的基础用法初始化仓库克隆现有的仓库添加暂存文件提交变动到仓库比较变动查看日志Git回退Git重置暂存区 Git版本管理重新提交取消暂存撤销对文件的修改 Git分支Git分支的优势Git…

5、注册字符类设备

字符设备 cdev结构体 Linux中使用cdev结构体描述一个字符设备。结构体定义在include/linux/cdev.h 文件中, struct cdev{struct kobject kobj;struct module *owner; //所属模块const struct file_operations *ops; //文件操作结构体struct list_head lis…

《Java初阶数据结构》----5.<二叉树的概念及使用>

前言 大家好,我目前在学习java。之前也学了一段时间,但是没有发布博客。时间过的真的很快。我会利用好这个暑假,来复习之前学过的内容,并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…

综合点评!史上最强开源大模型Llama 3.1

在人工智能领域,开源模型一直是推动技术进步和创新的重要力量。 北美时间7月23日,Meta公司(原Facebook)宣布了一项重大突破:开源模型Llama 3.1的正式发布。这一举措预示着AI技术的又一次飞跃,Llama 3.1有望…

虚拟化数据恢复—XenServer VPS不可用如何恢复数据?

虚拟化数据恢复环境: 某品牌R720服务器,4块STAT硬盘通过H710P阵列卡组建了一组raid10磁盘阵列。服务器上部署XenServer虚拟化平台,虚拟机安装Windows Server系统,作为Web服务器使用,运行SQL Server数据库。共有2个虚拟…

【数据结构】——堆的实现与算法

目录 一、堆的实现 1.1堆数据的插入 1.2堆数据的删除 二、建堆算法 2.1向上调整建堆 2.2向下调整建堆 三、堆的应用 3.1堆排序 3.2Top—K问题 一、堆的实现 1.1堆数据的插入 插入一个数据后不再是小堆需要将新数据调整到合适的位置,所以堆的插入就是在数组…

类和对象(中 )C++

默认成员函数就是用户不显示实现,编译器会自动实现的成员函数叫做默认成员函数。一个类,我们在不写的情况下,编译器会自动实现6个默认成员函数,需要注意,最重要的是前4个,其次就是C11以后还会增加两个默认成…

onlyoffice用nginx反向代理

我对于onlyoffice的需求就是当个在线编辑器使用。在集成react的时候之前都是写的绝对路径的地址,这样在需要迁移应用的时候就造成了巨大的麻烦,所以我决定用nginx做反向代理,这样我集成的时候就不用每次都修改源码中的地址了。 一开始写的代…

昇思25天学习打卡营第XX天|基于MindSpore通过GPT实现情感分类

其实数据集和模型的其他大平台接口的,感觉不用非包在自己包里 %env HF_ENDPOINThttps://hf-mirror.com mindnlp.transformers 库中的 GPTTokenizer 类来加载和处理与GPT(生成式预训练变换器)模型兼容的分词器,并添加特殊的控制标…

Spring源码(八)--Spring实例化的策略

Spring实例化的策略有几种 ,可以看一下 InstantiationStrategy 相关的类。 UML 结构图 InstantiationStrategy的实现类有 SimpleInstantiationStrategy。 CglibSubclassingInstantiationStrategy 又继承了SimpleInstantiationStrategy。 InstantiationStrategy I…

SpringBoot通过3种方式实现AOP切面

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

Sonar-Scanner: 静态代码分析的利器

Sonar-Scanner: 静态代码分析的利器 懂得享受生活的过程&#xff0c;人生才会更有乐趣。每个人都会遇到一些陷阱&#xff0c;每个人都有过去&#xff0c;有的甚至是失败的往事。过去的错误和耻辱只能说明过去&#xff0c;真正能代表人一生的&#xff0c;是他现在和将来的作为。…

【更新2022】省级农民专业合作社数量 无缺失 2006-2022

省级农民专业合作社数量是研究中国农村经济组织和农业社会化服务的重要数据。这些数据可以用来分析不同省份农业生产组织形式的多样性及其对农民生产、技术创新和收入增长的影响。研究者可以基于这些数据&#xff0c;探讨农民专业合作社在提升农产品质量、优化农业生产结构和推…

Transformer处理文本分类实例(Pytorch)

文章目录 Transformer处理文本分类实例参考网站我们构建一个实例问题,预测AG_NEWS的文本分类AG_NEWS数据集介绍预测目标总体思路(简述)主要流程数据预处理dataset构建(不是重点)构建词表 编写处理模型执行词嵌入位置编码(PositionalEncoding)(*核心)多层Transformer模块多头自注…

Mojo数据类型详解

Mojo 中的所有值都分配有相对应的数据类型&#xff0c;大多数类型都是由结构体定义的标称的类型。这些类型是标称的&#xff08;或“命名的”&#xff09;&#xff0c;因为类型相等性是由类型的名称而不是其结构决定的。 有一些类型未定义为结构&#xff0c;例如下面的两种情况…

百款精选的HTML5小游戏源码,你可以下载并直接运行在你的小程序或者自己的网站上

今天我带来了一份特别的礼物——百款精选的HTML5小游戏源码&#xff0c;你可以下载并直接运行在你的小程序或者自己的网站上&#xff0c;只需双击index.html即可开始。无论你是在寻找创意引流&#xff0c;还是想为你的网站增添互动性&#xff0c;这些小游戏都能帮你实现&#x…

办公必备!一键把PDF转换为PPT文件,只需这3款神器!

在当今数字化办公环境中&#xff0c;文件格式的转换已成为提高工作效率的关键因素之一。其中&#xff0c;PDF(便携式文档格式)和PPT(PowerPoint演示文稿)是两种广泛使用的文件格式。然而&#xff0c;有时我们需要将PDF文件转换为PPT格式&#xff0c;以便进行编辑或演示。 为方…