当前位置:

首页 > 编程开发 > 如何使用MySQL进行聚合查询?

如何使用MySQL进行聚合查询?

1、前言前面的内容已经把基础的增删改查介绍的差不多了,也介绍了表的相关约束,从本期开始往后的内容,就更加复杂了,更多的是一些复杂的查询SQL.2、插入查询结果查询还是用的比较多的,对于查询到的数据,能不能也给保存下来呢?也就是把查询的结果插入到另一张表中。案例:创建一张学生表,表中有id,name,sex,java,python这些字段,现需要把java成绩超过90的学生复制进java_result表,复制的字段为name,java。进行上述操作之前,我们需要创建一个学生表并准备好相关的数据:create

本文目录

      1、前言

      前面的内容已经把基础的增删改查介绍的差不多了,也介绍了表的相关约束, 从本期开始往后的内容,就更加复杂了,更多的是一些复杂的查询 SQL.

      2、插入查询结果

      查询还是用的比较多的,对于查询到的数据,能不能也给保存下来呢?也就是把查询的结果插入到另一张表中。

      案例:创建一张学生表,表中有 id,name,sex,java,python 这些字段,现需要把 java 成绩超过 90 的学生复制进 java_result 表,复制的字段为 name,java。

      进行上述操作之前,我们需要创建一个学生表并准备好相关的数据:

      create table student (
          id int primary key,
          name varchar(20),
          sex varchar(1),
          java float(5, 2)
      );
      insert into student value 
          (1, '张三', '男', 92.1),
          (2, '小红', '女', 88.2),
          (3, '赵六', '男', 83.4),
          (4, '王五', '男', 93.3),
          (5, '小美', '女', 96.0);

      有了学生表之后,我们要把 name,java 这两个字段的查询结果复制到 java_result 这个表中,这里我们注意,要求查询结果的临时表的列数和列的类型,要和 java_result 这里匹配,所以接下来我们就来创建 java_result 这张表:

      create table java_result (
          name varchar(20),
          java float(5, 2)
      );

      创建好 java_result 这张表之后,就要查询 student 表中 name java 两个字段,并且 java > 90,将满足上述条件的查询结果,插入到 java_result 表中!:

      insert into java_result select name, java from student where java > 90;
      -- Query OK, 3 rows affected (0.00 sec)
      -- Records: 3  Duplicates: 0  Warnings: 0
      select * from java_result;
      +--------+-------+
      | name   | java  |
      +--------+-------+
      | 张三   | 92.10 |
      | 王五   | 93.30 |
      | 小美   | 96.00 |
      +--------+-------+
      -- 3 rows in set (0.00 sec)

      这样我们就发现,已经将 student 表中 name 和 java 字段满足 > 90 的数据已经全部插入成功了!

      3、聚合查询

      前面我们接触过的 带表达式查询 都是列和列之间进行运算的,看哪一列满足了这个条件。

      而现在要介绍的聚合查询,就是针对 行和行 之间进行运算的! 

      3.1 聚合函数

      进行聚合查询,需要搭配聚合函数,下面介绍的函数都是 SQL 中内置的一组函数,我们先来简单的认识下:

      函数解释
      COUNT([DISTINCT] expr)返回查询到的数据的数量
      SUM([DISTINCT] expr)返回查询到的数据的总和,不是数字无意义
      AVG([DISTINCT] expr)返回查询到的数据的平均值,不是数字无意义
      MAX([DISTINCT] expr)返回查询到的数据的最大值,不是数字无意义
      MIN([DISTINCT] expr)返回查询到的数据的最小值,不是数字没有意义

      下面我们就来演示一下上述的聚合函数的简单使用,在使用之前,我们需要有一张表,并且有相应的数据:

      select * from student;
      +----+--------+------+-------+
      | id | name   | sex  | java  |
      +----+--------+------+-------+
      |  1 | 张三   | 男   | 92.10 |
      |  2 | 小红   | 女   | 88.20 |
      |  3 | 赵六   | 男   | 83.40 |
      |  4 | 王五   | 男   | 93.30 |
      |  5 | 小美   | 女   | 96.00 |
      |  6 | 李四   | 男   |  NULL |
      +----+--------+------+-------+
      -- 6 rows in set (0.00 sec)

      下面我们就针对上述这张表,来使用下上述的聚合函数。 

      3.1.1 count 

      ● 求出 student 表中有多少同学

      select count(*) from student;
      +----------+
      | count(*) |
      +----------+
      |        6 |
      +----------+
      -- 1 row in set (0.00 sec)

      这个操作就相当于先进行 select * ,然后针对返回的结果,在进行 count 运算,求结果集合的行数. 注意:此处如果有一列的数据全是 null,也会算进去!(因为是针对 *)

      此处这里的 count() 括号中,不一定写 *,可以写成任意的列明/表达式,所以我们可以针对 name 来统计人数:

      select count(name) from student;
      +-------------+
      | count(name) |
      +-------------+
      |           6 |
      +-------------+
      -- 1 row in set (0.00 sec)

       ● 统计有多少人有 java 考试成绩

      select count(java) from student;
      +-------------+
      | count(java) |
      +-------------+
      |           5 |
      +-------------+
      -- 1 row in set (0.00 sec)

      这里我们看到了,由于 count 是针对 java 字段进行统计,而 李四 那一条数据中,java 为 null,前面我们学习过,null 与任何值计算都是 null,所以统计的时候,就把 null 给去掉了。

      ● 统计 java 成绩大于90分的人数

      select count(java) from student where java > 90;
      +-------------+
      | count(java) |
      +-------------+
      |           3 |
      +-------------+
      -- 1 row in set (0.00 sec)

      这里我们要弄清楚,count() 这个括号中,是针对你要针对的那一列,针对不同列,不同的条件,就会有不同的结果,对于 count 的演示就到这里。

      注意:count 和 () 之间不能有空格,必须紧挨着,在 Java 中函数名和() 之间是可以有空格的,但很少人会这样写。

      3.1.2 sum

      这个聚合函数,就是把指定列的所有行进行相加得到的结果,要求这个列得是数字,不能是字符串/日期。

      ● 求出学生表中 java 考试分数总和

      select sum(java) from student;
      +-----------+
      | sum(java) |
      +-----------+
      |    453.00 |
      +-----------+
      -- 1 row in set (0.01 sec)

      虽然我们表中有 java 字段这列中有 null 值,前面了解到 null 与任何值运算都是 null,但是这里的 sum 函数会避免这种情况发生。

      当然在后面也可也带上 where 条件,这里就不做过多演示了。

      3.1.3 avg 

      ● 求班级中 java 的平均分

      select avg(java) from student;
      +-----------+
      | avg(java) |
      +-----------+
      | 90.600000 |
      +-----------+
      -- 1 row in set (0.00 sec)

      当前只是针对某一列进行平均运算,如果有两门课程,求每个学生总分的平均分呢?

      select avg(java + python) from student;

      这里每次查询结果都只有一列,能否把两个聚合函数一起使用呢?

      select sum(java), avg(java) as '平均分' from student;
      +-----------+-----------+
      | sum(java) | 平均分    |
      +-----------+-----------+
      |    453.00 | 90.600000 |
      +-----------+-----------+
      -- 1 row in set (0.00 sec)

      这里我们能发现一个细节,使用聚合函数查询,字段也是可以取别名的。

      3.1.4 max 和 min

      ● 求出 java 考试分数的最高分和最低分

      select max(java) as '最高分', min(java) as '最低分' from student;
      +-----------+-----------+
      | 最高分    | 最低分    |
      +-----------+-----------+
      |     96.00 |     83.40 |
      +-----------+-----------+
      -- 1 row in set (0.00 sec)

      上述就是聚合函数最基础的用法了, 但是在实际中也可能会有更复杂的情况,比如需要按照某某进行分组查询,这就需要搭配 GROUP BY 字句了。

      4、GROUP BY 子句

      select 中使用 group by 自居可以对指定列进行分组查询,但是需要满足指定分组的字段必须是 "分组依据字段",其他字段若想出现在 select 中,则必须包含在聚合函数中。

      这里我们构造出一张薪水表 salary:

      create table salary (
          id int primary key,
          name varchar(20),
          role varchar(20),
          income int 
      );
      insert into salary value 
          (1, '麻花疼', '老板', 5000000),
          (2, '篮球哥', '程序猿', 3000),
          (3, '歪嘴猴', '经理', 20000),
          (4, '多嘴鸟', '经理', 25000),
          (5, '雷小君', '老板', 3000000),
          (6, '阿紫姐', '程序猿', 5000);

      像上述的情况,如果要查平均工资,那公平吗???

      select avg(income) from salary;
      +--------------+
      | avg(income)  |
      +--------------+
      | 1342166.6667 |
      +--------------+
      -- 1 row in set (0.00 sec)

      那篮球哥的月薪连平均下来的零头都不到,所以这样去求平均工资是毫无意义的,真正有意义的是啥呢?求老板这个职位的平均工资,以及经理这个职位的平均工资,及程序猿这个职位的平均工资,通俗来说,就是按照 role 这个字段进行分组。每一组求平均工资:

      select role, avg(income) from salary group by role;
      +-----------+--------------+
      | role      | avg(income)  |
      +-----------+--------------+
      | 程序猿    |    4000.0000 |
      | 经理      |   22500.0000 |
      | 老板      | 4000000.0000 |
      +-----------+--------------+
      -- 3 rows in set (0.00 sec)

      这就也就是把 role 这一列,值相同的行给分成了一组,然后计算平均值,也是针对每个分组,分别计算。

      在 MySQL 中,这里得到的查询结果临时表,如果没有 order by 指定列排序,这里的顺序是不可预期的,当然也可以手动指定排序,比如最终结果按照平均工资降序排序:

      select role, avg(income) from salary group by role order by avg(income) desc;
      +-----------+--------------+
      | role      | avg(income)  |
      +-----------+--------------+
      | 老板      | 4000000.0000 |
      | 经理      |   22500.0000 |
      | 程序猿    |    4000.0000 |
      +-----------+--------------+
      -- 3 rows in set (0.00 sec)

      如果不带聚合函数的普通查询,能否可行呢?这里如果你没有修改任何配置文件,是不可行的,记住千万不能把前面的 order by 与 group by 弄混!

      5、HAVING 关键字

      分组查询也是可以指定条件的,具体三种情况:

      • 先筛选,再分组(where)

      • 先分组,再筛选(having)

      • 分组前分组后都指定条件筛选(where 和 having 结合使用)

      如何理解上述三条的含义呢? 这里我们举几个例子就很好理解了:

      ● 篮球哥月薪 3000 实在是太低了,简直给程序猿岗位拖后腿,干脆求平均工资时去掉篮球哥的月薪数据。

      select role, avg(income) from salary where name != '篮球哥' group by role;
      +-----------+--------------+
      | role      | avg(income)  |
      +-----------+--------------+
      | 程序猿    |    5000.0000 |
      | 经理      |   22500.0000 |
      | 老板      | 4000000.0000 |
      +-----------+--------------+
      -- 3 rows in set (0.00 sec)

      这样求出来的平均值就不包含篮球哥的月薪数据了,这就是先筛选,再分组。

      ● 还是查询每个岗位的平均工资,但是除去平均月薪在 10w 以上的岗位,不能让篮球哥眼红!

      select role, avg(income) from salary group by role having avg(income) < 100000;
      +-----------+-------------+
      | role      | avg(income) |
      +-----------+-------------+
      | 程序猿    |   4000.0000 |
      | 经理      |  22500.0000 |
      +-----------+-------------+
      -- 2 rows in set (0.00 sec)

      这样一来就只保留了平均月薪小于 10w 的岗位了,很明显这个平均值是在分组之后才算出来的,这也就是先分组,再筛选。

      这里 having 也能加上逻辑运算符,具体感兴趣的小伙伴可以自行下来尝试一下,好比如你想要拿好 offer,就得技术过关,还能加班!至于第三种分组前后都需要筛选,就是把上述俩例子结合起来,这里就不多赘述了!

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 MySQL
      相关文章 更多
      navicat导入数据库步骤详解及常见问题处理教程
      navicat导入数据库步骤详解及常见问题处理教程

      详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

      SQL主键约束和唯一约束有什么区别
      SQL主键约束和唯一约束有什么区别

      深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

      SQL约束有哪些类型及作用
      SQL约束有哪些类型及作用

      刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

      SQL游标常见错误排查:死锁与资源未释放问题
      SQL游标常见错误排查:死锁与资源未释放问题

      深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

      SQL中怎么创建和删除约束
      SQL中怎么创建和删除约束

      后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

      SQL分组统计查询:GROUP BY与HAVING子句用法示例
      SQL分组统计查询:GROUP BY与HAVING子句用法示例

      针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

      SQL Server与MySQL游标基本语法及完整代码示例
      SQL Server与MySQL游标基本语法及完整代码示例

      本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

      SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景
      SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景

      深入解析SQL中INNER JOIN与LEFT JOIN的核心区别。通过users和orders表实例,展示匹配行保留与NULL补位机制,重点讲解ON与WHERE子句中放置右表过滤条件的不同后果,提供防止LEFT JOIN退化的实战技巧及行数异常排查步骤。

      SQL CHECK约束的用法与取值范围限制
      SQL CHECK约束的用法与取值范围限制

      深入理解 SQL CHECK 约束在 PostgreSQL、MySQL 等数据库中的实现差异。文章通过订单业务场景,讲解如何定义单列范围与多列逻辑约束,分析 NULL 值对布尔条件的影响,并提供修改已有表结构时的安全操作建议,帮助开发者构建更健壮的数据完整性防线。

      SQL外键约束怎么用及级联操作说明
      SQL外键约束怎么用及级联操作说明

      后端开发中,如何正确使用 SQL 外键约束来维护订单与明细表的关系?本文通过 PostgreSQL 示例,深入讲解外键的创建语法、插入顺序要求,以及 ON DELETE CASCADE、RESTRICT、SET NULL 等策略的实际影响与风险控制,助你构建健壮的数据库结构。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。