MySQL知识汇总:讲一讲MySQL中Select语句的执行顺序

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL知识汇总:讲一讲MySQL中Select语句的执行顺序

MySQL中关键字段的执行顺序

一句话概括MySQL数据库中的select查询语句各个子句的执行顺序:

from >> (xxx join) >> where > group by >> 聚合 >>having >> select>> order by >> limit ,union关键字的执行顺序是不定的,需要具体情况具体分析;

一个丰满的SQL举例

查询语句都是从from开始执行的,每个步骤都会为下一个步骤生成一个虚拟表

(9) SELECT (10) DISTINCT <select_list>
(1) FROM <left_table> <right_table>
(3) <join_type> JOIN <right_table>
(2)  ON <join_condition>
(4).......join thirdTable on ......
(5) WHERE <where_condition>
(6) GROUP BY <group_by_list>
(7) WITH {CUBE|ROLLUP}
(8) HAVING <having_condition>
(11) ORDER BY <order_by_list>
(12) LIMIT <limit_number>

上述的SQL的查询过程

1:from执行from子句,前两个表执行第一个笛卡尔乘积,此时生成第一个虚拟表

什么是笛卡儿积?

当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象

2:上述形成的虚拟表各行基于on表达式进行筛选,留下符合的生成新的虚拟表

3:将在第二步中形成的虚拟表按照Left或者Right或者Outer关键字,这样生成新的虚拟表

具体过程是这样的

Left JOIN把左表记为基础保留表,缺失的数据使用外部行的方式向虚拟表中进行插入,右表部分为Null,形成新的虚拟表

RIGHT JOIN把右表记为基础保留表,缺失的数据使用外部行的方式向虚拟表中进行插入,左表部分为Null,形成新的虚拟表

4:超过两表关联的情况下,上述新生成的虚拟表和第三个表计算笛卡尔乘积,生成虚拟表,重复1-3的步骤,最终得到一个新的虚拟表

5:应用where筛选器,对上一步生产的虚拟表引用where筛选器,进行最终的数据过滤,生成新的虚拟表;

6:group by后边列中值一样的归为一组组合成为一组,得到新的虚拟表

7:应用cube或者rollup选项,生成超组,执行分组之后的聚合函数,生成新的虚拟表

在这里就不难理解,为什么不能使用计算表达式或者别名进行分组,因为

8:having筛选已分组数据,生成新的虚拟表

9:处理select子句,保留select后边定义的列,生成新的虚拟表

10:应用distinct子句,移除相同的行,生成新的虚拟表。

事实上如果应用了group by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的;

11:应用order by子句,此时返回的一个游标,而不是虚拟表。

正因为返回值是游标,那么使用order by 子句查询不能应用于表表达式,排序是很需要成本的,除非你必须要排序,否则最好不要指定order by,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。

12: Limit筛选返回的数据条数

对于包含outer join子句的查询,到底在on筛选器还是用where筛选器指定逻辑表达式呢?

on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outer join中还可以把移除的行再次添加回来,而where的移除的最终的;

Group函数的作用?

如果应用了group by,那么后面的所有步骤都只能得到的某一列的第一行的值,或者是聚合函数(count、sum、avg等)

原因在于最终的结果集中只为每个组包含一行。这一点请牢记,如果某一行没有使用聚集函数,默认返回第一行

是先执行group by还是先执行select

通过上面的SQL顺序执行可知,先进行group by 在进行select

为什么group by和select同时使用时,select中的字段必须出现在group by后或者聚合函数中。

如何实现数据去重

在SQL中可以通过关键字distinct去重,也可以通过group by分组实现去重,但实际上,如果数据量很大的话,使用distinct去重的效率会很慢,使用Group by去重的效率会更高,而且,很多distinct关键字在很多数据库中只支持对某个字段去重,无法实现对多个字段去重,如Postgresql数据库。(测试数据300w+,使用distinct去重需要十几秒,使用group by去重只需要几秒)。

应用HAVING过滤中可以使用聚合函数或者计算表达式或者别名进行过滤吗?

执行having的时候,已经执行过第六步的group by以及第七步的的聚合函数和计算表达式的以及别名。所以HAVING过滤中可以使用聚合函数或者计算表达式或者别名进行过滤吗

SELECT * FROM customers c
   LEFT JOIN orders o
   ON c.customer_id = o.customer_id
   WHERE c.city='HangZhou'
   GROUP BY c.customer_id
   HAVING  count(o.order_id) < 2;

哪些Column要放到Group by后边呢?

这是一个表

select country ccc,max(count),concat(country,max(count)) bbb,1,concat(country,count) from coutry group by ccc,concat(country,count)

我们在Select后边可以选择的列包括:自然列,单纯聚合函数、计算表达式(不含聚合函数)、常量、计算表达式(聚合函数)

其中:

group by后边可放可不放:常量

group by必须放:自然列、计算表达式(不含聚合函数)

group by不允许放:聚合函数、计算表达式(包含聚合函数)

注意:

单纯使用case when的话,属于计算表达式(不带聚合函数)如果使用group by的话,我们是必须和自然列一样把他放到group by后边的。

留一个问题:为什么select在order by之前,但是order by可以使用select后并不存在的列进行排序呢?

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
18天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
3月前
|
存储 关系型数据库 MySQL
在 MySQL 中使用 Insert Into Select
【8月更文挑战第11天】
531 0
在 MySQL 中使用 Insert Into Select
|
4月前
|
存储 关系型数据库 文件存储
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
47 2
|
5月前
|
关系型数据库 MySQL Linux
mysql 将select结果导出文件 linux
mysql 将select结果导出文件 linux
67 3
|
4月前
|
关系型数据库 MySQL 索引
MySQL之优化SELECT语句
以上只是一些基本的优化策略,具体的优化方案还需要根据实际的业务需求和数据情况来定制。
49 0
|
5月前
|
关系型数据库 MySQL 数据库
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
|
5月前
|
SQL 关系型数据库 MySQL
深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥
深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥
|
6月前
|
存储 SQL 关系型数据库
【MySQL进阶之路 | 基础篇】基本的SELECT语句及DESC显示表结构
【MySQL进阶之路 | 基础篇】基本的SELECT语句及DESC显示表结构
|
6月前
|
SQL 关系型数据库 MySQL
【MySQL】DQL-案例练习-DQL基本介绍&语法&执行顺序(代码演示)
【MySQL】DQL-案例练习-DQL基本介绍&语法&执行顺序(代码演示)
|
5月前
|
SQL 关系型数据库 MySQL
3.Mysql 基础语法和执行顺序
3.Mysql 基础语法和执行顺序
37 0