前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL 的执行顺序

SQL 的执行顺序

作者头像
白日梦想家
发布2020-07-18 18:32:48
2.2K0
发布2020-07-18 18:32:48
举报
文章被收录于专栏:SQL实现SQL实现

了解 SQL 的执行顺序非常有价值,它可以让我们写出语法正确的 SQL,帮助我们简化编写新查询的过程。

本文将在 MySQL 的基础上,介绍查询语句的执行顺序。下面是我们经常看到的查询语句的语法结构:

代码语言:javascript
复制
SELECT <select_list>FROM <left_table><join_type> JOIN <right_table>ON <join_condition>WHERE <where_condition>GROUP BY <group_by_list>HAVING <having_condition>ORDER BY <order_by_list>LIMIT <limit_number>

它的执行顺序:

  1. FROM / JOIN 和所有 ON 条件
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY
  7. LIMIT

以上是 SQL 标准定义的执行顺序。实际上,如果是简单的单表查询,即查询语句里面只包含了一张表,它将严格按照定义的执行顺序执行查询。对于多表查询,数据库有的时候并没有按此顺序运行查询,因为它们实现了一系列优化使查询运行更快。这些优化可能会改变实际的执行顺序,但它们最终必须返回与以默认的执行顺序运行查询的结果相同。

按照执行顺序的规则,排在后面的子句产生的结果不能被前面的子句引用。比如:

  1. 不能在 WHERE 子句里面使用 SELECT 子句设置的别名,因为 WHERE 子句先于 SELECT 子句执行;
代码语言:javascript
复制
# 执行失败,提示“Unknown column 'ename_job' in 'where clause'”SELECT   CONCAT(ename, '|', job) AS ename_job FROM  emp WHERE ename_job = 'KING|PRESIDENT'

2. 不能在 WHERE 子句里面过滤 GROUP BY 子句的聚合结果,因为 WHERE 子句先于 GROUP BY 子句执行;

代码语言:javascript
复制
# 执行不通过,提示“Invalid use of group function”SELECT   deptno,  COUNT(*) AS cnt FROM  emp WHERE COUNT(*) > 0GROUP BY deptno

3. 可以在 ORDER BY 子句中引用 GROUP BY 子句聚合的结果,因为 ORDER BY 子句的执行顺序在 GROUP BY 子句之后。

代码语言:javascript
复制
# 执行成功SELECT   deptno,  COUNT(*) FROM  emp GROUP BY deptno ORDER BY COUNT(*)

在 MySQL 里面,我们会看到一些“反常”的操作。

比如下面这条 SQL ,看起来像是 SELECT 子句的别名被 GROUP BY 子句引用。

代码语言:javascript
复制
SELECT   CONCAT(job, '|', deptno) AS job_dept,  COUNT(*) FROM  emp GROUP BY job_dept

那是不是说这条 SQL 破坏了前面定义的执行顺序呢?实际上并没有,MYSQL 会对这条 SQL 做重写,像这样:

代码语言:javascript
复制
SELECT   CONCAT(job, '|', deptno),  COUNT(*) FROM  emp GROUP BY CONCAT(job, '|', deptno)

再有,比如下面这条多表关联查询的语句。

代码语言:javascript
复制
SELECT   e.*,  d.dname FROM  emp e   LEFT JOIN dept d     ON d.deptno = e.deptno WHERE e.job = 'PRESIDENT'

假如 emp 表和 dept 都是很大的表,emp 通过条件 job = 'PRESIDENT' 过滤后会得到很小的结果集。如果按照标准的执行顺序先执行两个大表的 LEFT JOIN 再执行 WHERE 过滤,那整个 JOIN 操作将会占用很大的内存。MySQL 可能会对 emp 表先执行WHERE 子句的过滤操作,过滤后的结果集再和 dept 表关联。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档