SQL SELECT语句执行顺序

SELECT语句内部的执行步骤。

一条完整的SELECT语句内部的执行顺序是这样的:

  1. FROM子句组装数据(包括通过ON进行连接);
  2. WHERE子句进行条件筛选;
  3. GROUP BY分组 ;
  4. 使用聚集函数进行计算;
  5. HAVING筛选分组;
  6. 计算所有的表达式;
  7. SELECT 的字段;
  8. ORDER BY排序;
  9. LIMIT筛选。

查询是RDBMS中最频繁的操作。我们在理解SELECT语法的时候,还需要了解SELECT执行时的底层原理。只有这样,才能让我们对SQL有更深刻的认识。

其中你需要记住SELECT查询时的两个顺序:

1.关键字的顺序是不能颠倒的:

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

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的执行过程中,对于我们来说是不可见的。

我来详细解释一下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的基础上进行分组和分组过滤,得到中间的虚拟表vt3和vt4。

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

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

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

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

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

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

你要记住,在SELECT查询中,关键字的顺序是不能颠倒的,它们的顺序是:

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

另外需要注意的是,使用GROUP BY进行分组,如果想让输出的结果有序,可以在GROUP BY后使用ORDER BY。因为GROUP BY只起到了分组的作用,排序还是需要通过ORDER BY来完成。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程