MySQL:GROUP BY 分组查询

news2024/9/22 1:35:37

分组查询是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.coloradmin.cn/o/1964889.html

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

相关文章

笑出腹肌的饼图绘制秘籍:Matplotlib让你秒变数据烘焙大师!

1. 引言 亲们,还在为数据报告里的饼图头疼吗?别怕,Matplotlib来救场啦!它不只是个绘图工具,简直是数据界的魔术师,让你的饼图既专业又有趣。跟我学几招,保证让你的观众边吃边看,爱不…

Linux驱动开发—编写第一个最简单的驱动模块

文章目录 开发驱动准备工作1.正常运行的Linux系统的开发板2.内核源码树3.nfs挂载的rootfs4.得心趁手的IDE 第一个Hello world 驱动程序常见模块的操作命令模块的初始化和清理模块的版本信息模块中的各种宏 示例Hello World代码printk函数解析 使用MakeFile编译驱动模块使用insm…

谷歌账号异常,成功通过验证后这个界面操作指引:建议增加辅助手机和邮箱

许多朋友对下面这个界面都很熟悉,通常是账号被停用后的时候输入账号和密码后,还需要再次输入手机号码验证。而且这个时候输入国内的号码或者谷歌账号绑定的辅助手机号码都不管用,提示此电话号码用于验证的次数过多,或者此电话号码…

链表篇:03-合并有序链表

解题思路: 使用双指针,一个指针指向头节点,然后另外一个指针进行移动。让其头节点保持不动,最后循环遍历两个链表,将其挂到头指针所在的节点上。 temp 守卫节点,用于指向头节点,防止头节点丢…

机械学习—零基础学习日志(高数17——极限局部有界性)

零基础为了学人工智能,真的开始复习高数 这里我们更加详细讲解函数极限性质。上一篇文章里有一些内容还需要进一步补充。 局部有界性 这里是局部有界性的需要注意的事项。第3点,如果函数在闭区间内连续,则必定有界。试想一下,如…

Log4j2漏洞

Log4j2漏洞 步骤一:执行以下命令启动靶场环境并在浏览器访问!!! systemctl start docker cd vulhub/log4j/CVE-2021-44228 vi docker-compose.yml //编写docker-compose.xml的端口和版本号 docker-compose up -d # 访问网址 http://192.168.30.131:8983/solr/#/步骤二:先在自…

MyBatis入门如何使用操作数据库及常见错误(yml配置)

一,什么是MyBatis 是一款优秀的持久层框架,用于简化jdbc的开发 持久层:指的就是持久化操作的层,通常也就是数据访问层(dao),也就是用来操作数据库。 也就是MyBatis是让你更加简单完成程序与数…

ECCV 2024前沿科技速递:GLARE-基于生成潜在特征的码本检索点亮低光世界,低光环境也能拍出明亮大片!

在计算机视觉与图像处理领域,低光照条件下的图像增强一直是一个极具挑战性的难题。暗淡的光线不仅限制了图像的细节表现,还常常引入噪声和失真,极大地影响了图像的质量和可用性。然而,随着ECCV 2024(欧洲计算机视觉会议…

form表单按钮根据编辑/只读状态显示和隐藏

1. 场景阐述: form表单自定义按钮,在编辑模式显示,在只读模式隐藏 2. 效果: 这里的保存按钮是自定义按钮,在编辑状态的时候显示,非编辑状态下隐藏 3. 解决方案: 如下所示,只需要在按钮中添加odoo自带class类oe_edit_only即可 <header><button type"object"…

桌面管理利器:2024年度待办事项工具评选

国内外主流的10款待办事项桌面工具对比&#xff1a;PingCode、Worktile、滴答清单、番茄ToDo、Teambition、Tower、有道云笔记、TickTick、Any.do、Trello。 在忙碌的工作日中&#xff0c;管理日常任务和待办事项常常让人感到不胜其烦。选择合适的待办事项桌面工具&#xff0c;…

【Python实战因果推断】67_图因果模型2

目录 Are Consultants Worth It? Crash Course in Graphical Models Chains Are Consultants Worth It? 为了展示有向无环图(DAG)的力量&#xff0c;让我们考虑一个更有趣但处理因素并未随机化的情况。假设你是某公司的经理&#xff0c;正在考虑是否聘请顶级咨询顾问。你…

[数据结构] AVL树 模拟实现AVL树

标题&#xff1a;[数据结构] AVL树 && 模拟实现AVL树 水墨不写bug 正文开始&#xff1a; 目录 &#xff08;一&#xff09;普通二叉搜索树的痛点 &#xff08;二&#xff09;AVL树简介 &#xff08;1&#xff09;AVL树的概念 &#xff08;三&#xff09;AVL树的…

LeetCode面试150——189轮转数组

题目难度&#xff1a;中等 默认优化目标&#xff1a;最小化平均时间复杂度。 Python默认为Python3。 目录 1 题目描述 2 题目解析 3 算法原理及程序实现 3.1 暴力求解 3.2 循环链表 3.3 环状替代 3.4 数组翻转 4 题目难度 参考文献 1 题目描述 给定一个整数数组 nu…

运维.Linux.bash学习笔记.数组及其使用

运维专题 Bash Shell数组及其使用 此笔记当前仍在修改和编写。 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

基于N32L406+Freertos+letter_shell终端开源库移植

移植教程 这里首先感谢作者的开源 https://gitee.com/zhang-ge/letter-shell) [Letter shell 3.0 全新出发 | Letter (nevermindzzt.github.io)](https://nevermindzzt.github.io/2020/01/19/Letter shell 3.0全新出发/) 1.复制代码 将litter_shell文件夹中的所有文件复制到…

本地使用Git同步、配合Gitee同步至仓库并下拉到本地(亲手调试,全能跑通)

这几天在公司&#xff0c;同事都在使用Gitee上传项目&#xff0c;进行同步&#xff0c;我也进行了简单学习了解了一下版本控制软件Git&#xff0c;挺不错的&#xff0c;故写个笔记记录一下。 本篇博文主要涉及的内容&#xff1a; 1&#xff0c;本地写代码&#xff0c;通过Git同…

软件测试_接口测试面试题

接口测试是软件测试中的重要环节&#xff0c;它主要验证系统不同模块之间的通信和数据交互是否正常。在软件开发过程中&#xff0c;各个模块之间的接口是实现功能的关键要素&#xff0c;因此对接口进行全面而准确的测试是确保系统稳定性和可靠性的关键步骤。 接口测试的核心目…

树上dp学习总结2

今天也是侥幸刷了两道树上dp的问题&#xff0c;第一个还算简单&#xff0c;但是第二个真的可以说是我碰到的蓝题之首&#xff0c;做了一个晚上我只能留下了不争气的口水&#xff08;太饿了&#xff0c;该吃夜宵了&#xff09; P1131 [ZJOI2007] 时态同步 思路&#xff1a;一开…

RK3568笔记四十九:W25Q64驱动开发(硬件SPI1)

若该文为原创文章&#xff0c;转载请注明原文出处。 一、SPI介绍 串行外设接口 (Serial Peripheral interface) 简称 SPI&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并 且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚。 …

Word如何设置表格内容的中文和英文字体

1、选中需要设置的表格内容。 2、CtrlD&#xff0c;分别设置中文和英文字体&#xff0c;点确定即可。 提升自己最好的方法就是改变坏习惯&#xff0c;改变坏习惯最好的方法找习惯替代它。坏习惯不改&#xff0c;你永远受到限制&#xff0c;只能原地踏步。To do list&#xf…