MySQL数据库基础 08

news2024/11/26 23:48:37

第八章 聚合函数

  • 1. 聚合函数介绍
    • 1.1 AVG和SUM函数
    • 1.2 MIN和MAX函数
    • 1.3 COUNT函数
  • 2. GROUP BY
    • 2.1 基本使用
    • 2.2 使用多个列分组
    • 2.3 GROUP BY中使用WITH ROLLUP
  • 3. HAVING
    • 3.1 基本使用
    • 3.2 WHERE和HAVING的对比
  • 4. SELECT的执行过程
    • 4.1 查询的结构
    • 4.2 SELECT执行顺序
    • 4.3 SQL 的执行原理

1. 聚合函数介绍

  • 什么是聚合函数
    聚合函数作用于一组数据,并对一组数据返回一个值。
    在这里插入图片描述
  • 聚合函数类型
    • AVG()
    • SUM()
    • MAX()
    • MIN()
    • COUNT()
  • 聚合函数语法
    在这里插入图片描述
  • 聚合函数不能嵌套调用。比如不能出现类似“AVG(SUM(字段名称))”形式的调用。

1.1 AVG和SUM函数

可以对数值型数据使用AVG 和 SUM 函数。

SELECT AVG(salary), MAX(salary),MIN(salary), SUM(salary)
FROM   employees
WHERE  job_id LIKE '%REP%';

在这里插入图片描述

1.2 MIN和MAX函数

可以对任意数据类型的数据使用 MIN 和 MAX 函数。

SELECT MIN(hire_date), MAX(hire_date)
FROM	  employees;

在这里插入图片描述

1.3 COUNT函数

  • COUNT(*)返回表中记录总数,适用于任意数据类型
SELECT COUNT(*)
FROM	  employees
WHERE  department_id = 50;

在这里插入图片描述

  • COUNT(expr) 返回expr不为空的记录总数。
SELECT COUNT(commission_pct)
FROM   employees
WHERE  department_id = 50;

在这里插入图片描述

  • 问题:用count(*),count(1),count(列名)谁好呢?

其实,对于MyISAM引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。

Innodb引擎的表用count(*),count(1)直接读行数,复杂度是O(n),因为innodb真的要去数一遍。但好于具体的count(列名)。

  • 问题:能不能使用count(列名)替换count(*)?

不要使用 count(列名)来替代 count(*)count(*)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。

说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

2. GROUP BY

2.1 基本使用

在这里插入图片描述
可以使用GROUP BY子句将表中的数据分成若干组

SELECT column, group_function(column)
FROM table
[WHERE	condition]
[GROUP BY	group_by_expression]
[ORDER BY	column];

在SELECT列表中所有未包含在组函数中的列都应该包含在 GROUP BY子句中

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

在这里插入图片描述
包含在 GROUP BY 子句中的列不必包含在SELECT 列表中

SELECT   AVG(salary)
FROM     employees
GROUP BY department_id ;

在这里插入图片描述

2.2 使用多个列分组

在这里插入图片描述

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

在这里插入图片描述

2.3 GROUP BY中使用WITH ROLLUP

使用WITH ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量。

SELECT department_id,AVG(salary)
FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;

注意:
当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的。

3. HAVING

3.1 基本使用

在这里插入图片描述
过滤分组:HAVING子句

  1. 行已经被分组。
  2. 使用了聚合函数。
  3. 满足HAVING 子句中条件的分组将被显示。
  4. HAVING 不能单独使用,必须要跟 GROUP BY 一起使用。
    在这里插入图片描述
SELECT   department_id, MAX(salary)
FROM     employees
GROUP BY department_id
HAVING   MAX(salary)>10000 ;

在这里插入图片描述

  • **非法使用聚合函数 : 不能在 WHERE 子句中使用聚合函数。**如下:
SELECT   department_id, AVG(salary)
FROM     employees
WHERE    AVG(salary) > 8000
GROUP BY department_id;

3.2 WHERE和HAVING的对比

区别1:WHERE 可以直接使用表中的字段作为筛选条件,但不能使用分组中的计算函数作为筛选条件;HAVING 必须要与 GROUP BY 配合使用,可以把分组计算的函数和分组字段作为筛选条件。

这决定了,在需要对数据进行分组统计的时候,HAVING 可以完成 WHERE 不能完成的任务。这是因为,在查询语法结构中,WHERE 在 GROUP BY 之前,所以无法对分组结果进行筛选。HAVING 在 GROUP BY 之后,可以使用分组字段和分组中的计算函数,对分组的结果集进行筛选,这个功能是 WHERE 无法完成的。另外,WHERE排除的记录不再包括在分组中。

区别2:如果需要通过连接从关联表中获取需要的数据,WHERE 是先筛选后连接,而 HAVING 是先连接后筛选。 这一点,就决定了在关联查询中,WHERE 比 HAVING 更高效。因为 WHERE 可以先筛选,用一个筛选后的较小数据集和关联表进行连接,这样占用的资源比较少,执行效率也比较高。HAVING 则需要先把结果集准备好,也就是用未被筛选的数据集进行关联,然后对这个大的数据集进行筛选,这样占用的资源就比较多,执行效率也较低。

小结如下:

优点缺点
WHERE先筛选数据再关联,执行效率高不能使用分组中的计算函数进行筛选
HAVING可以使用分组中的计算函数在最后的结果集中进行筛选,执行效率较低

开发中的选择:
WHERE 和 HAVING 也不是互相排斥的,我们可以在一个查询里面同时使用 WHERE 和 HAVING。包含分组统计函数的条件用 HAVING,普通条件用 WHERE。这样,我们就既利用了 WHERE 条件的高效快速,又发挥了 HAVING 可以使用包含分组统计函数的查询条件的优点。当数据量特别大的时候,运行效率会有很大的差别。

4. SELECT的执行过程

4.1 查询的结构

#方式1:
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

#方式2:
SELECT ...,....,...
FROM ... JOIN ... 
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

#其中:
#(1)from:从哪些表中筛选
#(2)on:关联多表查询时,去除笛卡尔积
#(3)where:从表中筛选的条件
#(4)group by:分组依据
#(5)having:在统计结果中再次筛选
#(6)order by:排序
#(7)limit:分页

4.2 SELECT执行顺序

你需要记住 SELECT 查询时的两个顺序:
1. 关键字的顺序是不能颠倒的:

SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT...

2.SELECT 语句的执行顺序(在 MySQL 和 Oracle 中,SELECT 执行顺序基本相同):

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT 的字段 -> DISTINCT -> ORDER BY -> LIMIT

在这里插入图片描述
比如你写了一个 SQL 语句,那么它的关键字顺序和执行顺序是下面这样的:

SELECT DISTINCT player_id, player_name, count(*) as num # 顺序 5
FROM player JOIN team ON player.team_id = team.team_id # 顺序 1
WHERE height > 1.80 # 顺序 2
GROUP BY player.team_id # 顺序 3
HAVING num > 2 # 顺序 4
ORDER BY num DESC # 顺序 6
LIMIT 2 # 顺序 7

在 SELECT 语句执行这些步骤的时候,每个步骤都会产生一个虚拟表,然后将这个虚拟表传入下一个步骤中作为输入。需要注意的是,这些步骤隐含在 SQL 的执行过程中,对于我们来说是不可见的。

4.3 SQL 的执行原理

SELECT 是先执行 FROM 这一步的。在这个阶段,如果是多张表联查,还会经历下面的几个步骤:

  1. 首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;
  2. 通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;
  3. 添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。

当然如果我们操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得到是我们的原始数据。

当我们拿到了查询数据表的原始数据,也就是最终的虚拟表 vt1,就可以在此基础上再进行 WHERE 阶段。在这个阶段中,会根据 vt1 表的结果进行筛选过滤,得到虚拟表 vt2

然后进入第三步和第四步,也就是 GROUP 和 HAVING 阶段。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3vt4

当我们完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT 阶段

首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表 vt5-1vt5-2

当我们提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段,得到虚拟表 vt6

最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段,得到最终的结果,对应的是虚拟表 vt7

当然我们在写 SELECT 语句的时候,不一定存在所有的关键字,相应的阶段就会省略。

同时因为 SQL 是一门类似英语的结构化查询语言,所以我们在写 SELECT 语句的时候,还要注意相应的关键字顺序,所谓底层运行的原理,就是我们刚才讲到的执行顺序。

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

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

相关文章

MT1619

MT1619 是一款PD快充开关电源转换器芯片,其内部集成了一颗高集成度、高性能的电流模式 PWM 控制器和一颗功率 MOSFET。它适用于小于 30W 的开关电源设备。MT1619 具有恒功率功能,特别适用于 PD 充电器、电源适配器等中小功率的开关电源设备。极低的启动电…

[golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群

一.服务发现介绍 引入 上一节讲解了使用 gRPC创建微服务,客户端的一个接口可能需要调用 N个服务,而不同服务可能存在 不同的服务器,这时,客户端就必须知道所有服务的 网络位置(ipport),来进行连接服务器操作,如下图所示: 以往的做…

赋值运算符重载实例:Date类(结尾附源码)

赋值运算符重载实例:Date类 文章目录 赋值运算符重载实例:Date类一、构造日期类二、获取某年某月天数以及检查合法1.获取某年某月天数2.检查日期合法3.打印日期类 三、不同运算符的重载(1) ; !(2)> ; &g…

Lecture 13 Formal Language Theory Finite State Automata

目录 什么是语言?Formal Language Theory 形式语言理论动机例子除了从属问题之外的问题Regular Languages 正则语言Finite State Acceptor 正则语言的性质Derivational MorphologyWeighted FSAFinite State Transducer (FST)FST for Inflectional MorphologyNon-Reg…

Java Web实现用户登录功能

文章目录 一、纯JSP方式实现用户登录功能(一)实现思路1、创建Web项目2、创建登录页面3、创建登录处理页面4、创建登录成功页面5、创建登录失败页面6、编辑项目首页 (三)测试结果 二、JSPServlet方式实现用户登录功能(一…

软考A计划-系统架构师-官方考试指定教程-(11/15)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

第四十周周报

学习目标: 一、Stable Diffusion 论文 学习时间: 2023.6.3-2023.6.9 学习产出: 一、模型进展 相比前两周的结果,本周改进了一下参数,FID达到了9 前两周结果为10.258 本周相比前两周FID降低1 二、High-Resolu…

数据结构之树与二叉树——算法与数据结构入门笔记(五)

本文是算法与数据结构的学习笔记第五篇,将持续更新,欢迎小伙伴们阅读学习。有不懂的或错误的地方,欢迎交流 引言 前面章节介绍的都是线性存储的数据结构,包括数组、链表、栈、队列。本节带大家学习一种非线性存储的数据结构&…

【MySQL】- 05 sql 语句练习题

sql 语句练习题 一 测试数据的准备二、数据查询1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩4、…

MySQL数据库基础 06

第六章 多表查询 1. 一个案例引发的多表连接1.1 案例说明1.2 笛卡尔积(或交叉连接)的理解1.3 案例分析与问题解决 2. 多表查询分类讲解分类1:等值连接 vs 非等值连接等值连接非等值连接 分类2:自连接 vs 非自连接分类3&#xff1a…

动态网站开发02:Java Web概述

文章目录 一、 XML基础(一)XML概述1、XML2、XML与HTML的比较 (二)XML语法1、XML文档的声明2、XML元素的定义3、XML属性的定义4、XML注释的定义5、XML文件示例 (三)DTD约束1、什么是XML约束2、什么是DTD约束…

MM32F3273G8P火龙果开发板MindSDK开发教程5 - Gcc编译环境的配置

MM32F3273G8P火龙果开发板MindSDK开发教程5 - Gcc编译环境的配置 1、准备工作 用了几天Keil后,实在用不习惯,只好回到macos系统中来搭建gcc的编译环境。但是百问网火龙果开发板自带的DAP-Link在pyocd中根本识别不到,所以烧录还需要重新购置…

MySQL数据库基础 07

第七章 单行函数 1. 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类 2. 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换 3. 字符串函数4. 日期和时间函数4.1 获取日期、时间 4.2 日期与时间戳的转换 4.3 获…

一个关于宏定义的问题,我和ChatGPT、NewBing、Google Bard、文心一言 居然全军覆没?

文章目录 一、问题重述二、AI 解题2.1 ChatGPT2.2 NewBing2.3 Google Bard2.4 文心一言2.5 小结 一、问题重述 今天在问答模块回答了一道问题,要睡觉的时候,又去看了一眼,发现回答错了。 问题描述:下面的z的值是多少。 #define…

【Redis】Redis持久化机制RDB与AOF

目录 一、RDB 1、概念 2、RDB文件保存 3、执行RDB 4、触发RDB 5、fork原理 6、RDB的缺点 二、AOF 1、概念 2、开启AOF 3、触发AOF 4、触发重写AOF 三、区别 一、RDB 1、概念 RDB全称为Redis Database Backup File(Redis数据备份文件)&…

提示工程师指南3-Prompt工程-高级提示

高阶Prompting 到这一步,应该很明显,改进提示有助于在不同任务上获得更好的结果。这就是Prompt工程背后的整个理念。 虽然之前的例子很有趣,但在我们深入了解更高级的概念之前,让我们先正式地介绍一些概念。 文章目录 高阶Promp…

中国机器元宇宙手术机器人市场迎来爆发期,思哲睿能否借势上市?

手术机器人作为一种能够辅助医生进行精准、微创的外科手术的高端医疗设备,近年来受到了国内外医疗界的广泛关注和重视。随着我国人口老龄化、医疗需求增加、医疗技术进步等因素的推动,手术机器人市场规模呈现快速增长态势。 在这样一个充满机遇和挑战的市…

docker部署prometheus+grafana视图监控

效果 一、grafana可视化平台部署 docker run -d \--namegrafana \--restartalways \-p 3000:3000 \grafana/grafanagrafana我也是部署在170.110服务器上,192.168.170.110:3000访问grafana 默认账号密码都是admin 二、部署exportor采集信息 针对各类数据库平台系统…

ASP.NET Core MVC 从入门到精通之Html辅助标签补充及模型校验基础

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生&#xff0c…

7. user-Agent破解反爬机制

文章目录 1. 为什么要设置反爬机制2. 服务器如何区分浏览器访问和爬虫访问3. 反爬虫机制4. User-Agent是什么5. 如何查询网页的User-Agent6. user-agent信息解析7. 爬虫程序user-agent和浏览器user-agent的区别8. 代码查看爬虫程序的user-agent9. 在代码中加入请求头信息 1. 为…