Mysql中Select语句的执行顺序

目录

前言

试验环境

一、语句结构

二、执行步骤

三、查询过程

四、疑问

总结

前言

今天同事问了我个问题,select语句中的别名可以在哪些地方使用,一听这个我就想到了聚合函数、group by、having、order by 。然后它又问我可以在 join on中使用嘛?,我陷入了思考,想了下这其实跟select语句的执行顺序有关,因为记不太清了,所以再次学习了下,并记录一下。

试验环境

Mysql 5.7

一、语句结构

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

二、执行步骤

在MySQL中,SELECT语句的执行顺序可以分为以下几个步骤:

  1. FROM子句:首先,MySQL会从FROM子句中指定的表中检索数据。如果FROM子句中包含多个表,MySQL会根据连接条件将它们连接起来。

  2. ON子句:接下来,MySQL会根据ON子句中的条件过滤出符合条件的数据。

  3. WHERE子句:然后,MySQL会根据WHERE子句中的条件过滤出符合条件的数据。只有符合WHERE条件的数据才会被查询出来。

  4. GROUP BY子句:如果查询语句中有GROUP BY子句,MySQL会根据GROUP BY子句中指定的列对查询结果进行分组。每个分组都会有一个唯一的组标识。

  5. 聚合函数

  6. HAVING子句:如果查询语句中有HAVING子句,MySQL会根据HAVING子句中的条件过滤出符合条件的分组。只有符合HAVING条件的分组才会被查询出来。

  7. SELECT子句:接下来,MySQL会根据SELECT子句中指定的列从查询结果中提取出需要的数据。

  8. DISTINCT关键字:如果查询语句中包含DISTINCT关键字,MySQL会去除查询结果中的重复行。

  9. ORDER BY子句:如果查询语句中有ORDER BY子句,MySQL会根据ORDER BY子句中指定的列对查询结果进行排序。

  10. LIMIT子句:最后,如果查询语句中有LIMIT子句,MySQL会根据LIMIT子句指定的数量限制查询结果的行数。

总体来说,SELECT语句的执行顺序是按照以上步骤逐步执行的。根据查询语句中的不同子句,MySQL会在执行过程中进行不同的操作,最终返回符合条件的查询结果。

三、查询过程

  1. 首先根据FROM后边的前两个表做一个笛卡尔积生成虚拟表table1,对应步骤1
    笛卡尔积
    
    笛卡尔积是集合论中的一个概念,表示两个集合的所有可能的有序对组成的集合。
    
    假设A和B是两个集合,A={a, b},B={1, 2}。那么A和B的笛卡尔积可以表示为A×B
    ={(a, 1), (a, 2), (b, 1), (b, 2)}。
    
    简单来说,笛卡尔积就是将两个集合的每个元素进行组合,得到所有可能的有序对。
    结果集合中的每个元素都由一个A中的元素和一个B中的元素组成,且顺序不同则为
    不同的元素。
  2. 然后根据ON语句的条件对table1进行筛选生成table2,对应步骤2
  3. 然后根据连接关键字Left、Right、Outer等,对table2进行补充形成table3
    具体过程
    Left 左表为基础表,右表对应数据不存在则为Null,形成新的虚拟表
    RIGHT 右表为基础表,左表对应数据不存在则为Null,形成新的虚拟表
  4. 如果超过两张表就重复1-3最终形成虚拟表table4
  5. 通过where语句进行筛选,形成虚拟表table5,对应步骤3
  6. 有group by 语句,就对table5分组形成 虚拟表table6,对应步骤4
  7. 应用cube或者rollup选项,生成超组,对分组后结果执行聚合函数形成虚拟表table7,对应步骤5
    cube、rollup选项是什么?
    
    CUBE和ROLLUP都是用于生成多维聚合报表的选项。
    
    CUBE选项允许在GROUP BY子句中同时生成多个聚合级别的汇总数据。它会生成所有可能的组合,
    包括空值。例如,如果有两个维度A和B,那么CUBE(A, B)将生成包括(A,B),(A,NULL),
    (NULL,B)和(NULL,NULL)的所有组合。
    
    ROLLUP选项类似于CUBE,但是它只生成按照指定顺序的聚合级别。ROLLUP(A, B)将生成(A,B)
    ,(A,NULL)和(NULL,NULL)这三个级别的组合。
    
  8. 执行having 语句,对分组进行筛选形成虚拟表table8,对应步骤6
  9. 应用select语句,保留相应的列,生成虚拟表table9,对应步骤7
  10. 有DISTINCT语句,移除重复行,生成虚拟表table10,对应步骤8
  11. 执行order by子句,此时返回的一个游标,对应步骤9
    什么是游标?
    MySQL游标是一个用于在数据集上进行迭代的数据库对象。它类似于在编程中使用的游标概念,
    可以将游标看作是一个指针,可以依次访问数据集中的每一行。
  12. Limit筛选返回的数据条数,对应步骤10

四、疑问

分析完mysql的执行顺序,很明显别名不可以在join on中使用,因为join on在select之前就执行了,但是我又产生了新的疑问:

  1. select在group by之后执行,为什么group by中可以使用别名?
  2. 用on筛选和用where筛选有什么区别?
  3. order by在select之后,为什么order by可以用select中未选择的列呢?

问题1:select在group by之后执行,为什么group by中可以使用别名?

mysql官网也没有给出具体原因
mysql官网解释

但目前可以确定的是:select肯定在group by之前执行了一次,可以理解成在原有顺序的基础上的预加载,也就是说对于mysql,每一次运行代码,实际上执行了至少两次select。

问题2:用on筛选和用where筛选有什么区别?

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

问题3:order by在select之后,为什么order by可以用select中未选择的列呢?

没找到答案,希望大佬可以解惑。

总结

本文总结了mysql中select的执行顺序,并对几个常见的疑问进行了解答,希望能对你有所帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alpaca Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值