一、SQL 书写顺序和执行顺序
二、SQL 执行顺序
从上面的图中我们可以看出 SELECT、FROM 子句是必选的其它子句如 WHERE 子句、GROUP BY 子句等是可选的.
一个 SELECT 语句中,子句的顺序是固定的.必须严格按照上述的顺序书写.
所有的查询语句都是从 FROM 开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入.
在说明 SQL 执行的具体步骤之前,我们先准备两张表 department、employee ,然后以这两张表演示整个 SQL 的执行过程
下面我们就以这条 SQL 为例
SELECT
DISTINCT
e.name,e.age,d.id,d.location
FROM employee e
LEFT JOIN department d
ON e.depId=d.id
WHERE d.id IS NOT NULL
GROUP BY e.id
HAVING e.age >= 16
ORDER BY e.age
LIMIT 0,2;
1、先对 FROM 子句后面的两张表执行笛卡尔乘积,生成虚拟表 virtual table 1
employee 表的第一行记录关联 department 表的所有行,接着 employee 表的第二行记录关联 department 表的所有行,以此类推...得到的结果如下
2、使用 ON 条件筛选器,将 ON 中的逻辑表达式应用到 virtual table 1 中的各个行,筛选出满足 ON 中逻辑表达式的行,生成虚拟表 virtual table 2
3、根据 JOIN_TYPE 来判断是否需要添加外部行,生成虚拟表 virtual table 3
这一步只有连接类型为 OUTER JOIN 时才会发生,例如 LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN, OUTER 关键字就是外部行的意思,但是在大多数的时候,我们都是会省略掉 OUTER 关键字的
注意:如果是 INNER JOIN ,则不需要添加外部行,也不会生成虚拟表 virtual table 3,还是沿用上面的虚拟表 virtual table 2,为了同步,我们也称它为 virtual table 3
3.1、LEFT [OUTER] JOIN : 标记左表为保留表,即把左表被 ON 条件筛选掉的记录添加回来,右表空余的的部分以 NULL 填充
3.2、RIGHT [OUTER] JOIN : 标记右表为保留表,即把右表被 ON 条件筛选掉的记录添加回来,左表空余的的部分以 NULL 填充
3.3、FULL [OUTER] JOIN : 标记左表和右表为保留表,把它们被 ON 条件筛选掉的记录都添加回来
注:如果 FROM 子句中表的数目大于 2 ,那么就将我们上面得到的 virtual table 3 与第三张表重复上述的 1-3 步骤,生成新的 virtual table 3
4、使用 WHERE 条件筛选器对上面生成的 virtual table 3 进行筛选,生成虚拟表 virtual table 4
这里有一个细节点需要提一下,如果我们有一个 condition 需要去筛选,是使用 ON 筛选器还是 WHERE 筛选器呢?
ON 筛选器和 WHERE 筛选器最大的区别是: ON 筛选器过滤掉的记录可以通过第三步的 JOIN 重新添加回来,而 WHERE 筛选器过滤掉的记录是不可挽回的
5、GROUP BY 子句将具有相同属性的记录组合成一组,生成虚拟表 virtual table 5
6、使用 CUBE 或者 ROLLUP 选项,为 virtual table 5 生成超组,生成虚拟表 virtual table 6
7、使用 HAVING 条件筛选器对上面生成的 virtual table 6 进行筛选,生成虚拟表 virtual table 7
8、处理 SELECT子句,将 virtual table 7 中的并且在 Select_list 中的列筛选出来,生成虚拟表 virtual table 8
9、使用 DISTINCT 子句,将虚拟表 virtual table 8 中相同的记录移除,生成虚拟表 virtual table 9
10、使用 ORDER BY 子句,按照 order_by_condition 排序 virtual table 9,生成虚拟表 virtual table 10
11、最后使用 LIMIT 取出符合条件的记录