Skip to content

SELECT 语句的完整结果

sql
# SQL92
SELECT ..., ...(可能存在聚合函数)
FROM ..., ...(多表的连接)
WHERE ...(多表的连接条件)
AND ...(不包含聚合函数的过滤条件)
GROUP BY ...(分组)
HAVING ...(包含聚合函数的过滤条件)
ORDER BY ...(排序)
LIMIT ... (分页)

# SQL99
SELECT ..., ...(可能存在聚合函数)
FROM ...
JOIN ...(多表的连接)
ON ...(多表的连接条件)
JOIN ...(多表的连接)
ON ...(多表的连接条件)
WHERE ...(不包含聚合函数的过滤条件)
AND ...(不包含聚合函数的过滤条件)
GROUP BY ...(分组)
HAVING ...(包含聚合函数的过滤条件)
ORDER BY ...(排序)
LIMIT ... (分页)

SQL 的执行顺序

SELECT ... FROM ... (LEFT / RIGHT) JOIN ... ON ... (LEFT / RIGHT) JOIN ON... WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY LIMIT

  • 先执行 FROM。在这个阶段,如果是多张表联查,还会经历下面的几个步骤:

    • 首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;

    • 通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;

    • 添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在 虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。

    如果我们操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得 到是我们的原始数据。

  • GROUP 和 HAVING 阶段 。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组 过滤,得到中间的虚拟表 vt3 和 vt4 。当我们完成了条件筛选部分之后,就可以筛选表中提取 的字段,也就是进入到 SELECT 和 DISTINCT阶段 。

  • 首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到 中间的虚拟表vt5-1 和 vt5-2 。当我们提取了想要的字段数据之后,就可以按照指定的字段 进行排序,也就是 ORDER BY 阶段 ,得到虚拟表 vt6 。最后在 vt6 的基础上,取出指定行的 记录,也就是 LIMIT 阶段 ,得到最终的结果,对应的是虚拟表vt7 。当然我们在写 SELECT 语句的时候,不一定存在所有的关键字,相应的阶段就会省略。