MySQL关键字执行顺序

一、 关键字书写顺序

select
distinct
from
join
on
where
group by
having
union (all)
order by
limit

二、 关键字实际执行顺序

from
on
join
where
group by
having
select
distinct
union (all)
order by
limit

三、 解读

执行过程: Mysql会先执行from,然后根据on关键字去筛选目标表,筛选出的结果再进行join,这样就会形成一个临时表。然后去执行where条件去筛选这个临时表,这样基本就筛选出需要的数据了。然后就可以对数据进行group by进行分组,同时若是有必要就会再执行having对数据进行进一步筛选,这里执行完数据基本就是一定定型了,下面就需要select去筛选目标列了,完事之后需要使用distinct进行去重这样一个表的查询基本就结束了。若是需要多表查询则还需要使用union或者union all来进行连接多表的结果。然后就是对数据进行排序的order by ,排完顺序自然就是取分页了。这样就会将一个完整的sql执行完毕了。

1. from

指定表,指定需要那些表来检索数据。
① 后面跟单表,直接执行下一步:where;
②后面跟隐式内连接(table1,table2 或 cross join),会先求笛卡尔积,生成虚拟表V1;之后如果是table1,table2,下一步执行where;如果是cross join on,下一步执行on;
③内连接、左外连接、右外连接,下一步执行on;

2. on

筛选条件。用于多表查询,配合join使用,根据on的条件筛选出满足条件的行,生成虚拟表V2。
注意:当使用 inner join 或 cross join 时,无论on后面写的是什么条件,都会被翻译成where语句。此时使用on语句其实就是在使用where。例如:
原始SQL:

select a.user_id from sys_user  a 
inner join sys_user_role  b on a.user_id = b.user_id; 

被执行优化器优化后的sql(mysql真正执行的语句):

select `a`.`user_id` AS `user_id` from `sys_user` `a` 
join `sys_user_role` `b` where (`a`.`user_id` = `b`.`user_id`)
3. join

连接方式,用于多表查询。
注意:
inner join 和 cross join 都会进行笛卡尔积;笛卡尔积是指两个表直接关联,得到的临时数据条数为m*n;笛卡尔积对数据量大的表来说会造成灾难性的后果,所以优先选择 left join/right join。

4. where

筛选条件。
where和on的区别
①先执行on,后执行where;
②on用于建立关联关系,在生成临时表是执行;where用于生成临时表后对数据进行筛选;
③on可以更好地提高效率,应该优先使用on;

5. group by

分组条件,根据 group by 指定的列或者列函数进行分组;
使用 group by 时需注意:select 的列名必须是分组列或者聚合函数;

6. having

分组筛选条件,对分组后的结果进行再次筛选;

7. select

返回数据列表。

8. distinct

去重。一般用于一个字段;若有多个字段时,则会对多个字段进行组合去重,只有多个字段组合起来的值是相等的才会被去重。

9. union(all)

数据合并。union(all)在 order by 执行之前执行,所以,在使用 union 组合查询时,只能使用一个 order by,而且它必须出现在最后一条 select 语句之后。

10. order by

排序。

11. limit

查询结果行数限制。

四、文章来源

https://blog.youkuaiyun.com/weixin_47410172/article/details/127750217
https://blog.youkuaiyun.com/m0_46897923/article/details/125114998

### MySQL 查询解析与执行顺序 在构建复杂的 SQL 查询时,理解各个子句的处理顺序至关重要。尽管书写查询语句遵循特定的语法结构 `(1)-(6)`[^1],实际执行流程可能有所不同。 #### FROM 子句 作为查询的第一步,`FROM` 定义了操作的数据源表或视图。此阶段涉及任何必要的连接逻辑以及初步的数据集准备。 ```sql FROM table_name AS alias JOIN another_table ON condition; ``` #### WHERE 过滤条件 紧随其后的 `WHERE` 用于限定记录范围,在这里可以应用各种过滤表达式来缩小目标数据集合[^2]。 ```sql WHERE column_value > threshold AND other_column IS NOT NULL; ``` #### GROUP BY 分组依据 一旦通过 `WHERE` 条件筛选出了基础数据集,则按照指定列进行分组汇总计算。这一步骤创建了一个新的临时结果集,其中每一行代表一组具有共同特征的数据项[^3]。 ```sql GROUP BY category_id, year_month; ``` #### HAVING 组级过滤器 不同于作用于单条记录上的 `WHERE`,`HAVING` 是用来进一步筛除不符合某些聚合函数约束条件的整体分组[^4]。 ```sql HAVING COUNT(*) >= minimum_count OR SUM(sales_amount) BETWEEN lower_bound AND upper_bound; ``` #### SELECT 字段列表 此时才真正确定最终输出哪些字段给用户查看;同时也可以在此处定义别名简化展示效果或者调用内置/自定义函数加工原始数值。 ```sql SELECT user_id, MAX(order_date), AVG(item_price); ``` #### ORDER BY 排序指令 最后一步是对上述所有步骤产生的结果实施排序安排,确保按需呈现有序的信息流。 ```sql ORDER BY total_sales DESC, product_name ASC; ``` #### LIMIT 结果数量控制 (可选) 对于部分数据库系统而言,还可以附加一个 `LIMIT` 参数以限制返回的最大行数,但这并非标准SQL的一部分而是扩展特性之一。 ```sql LIMIT top_n_results OFFSET skip_first_m_records; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值