手写顺序
SELECT DISTINCT
<select list>
FROM
<left_table> join <join_type> JOIN <right_table> ON <join_condition>
WHERE
<where_condition>
GROUP BY
<group_by_list>
HAVING
<having_condition>
ORDER BY
<order_by_condition>
LIMIT <limit_number>
机读顺序
1. FROM <left_table>
2. ON <join_condition>
3. <join_type> JOIN <right_table>
4. WHERE <where_condition>
5. GROUP BY <group_by_list>
6. HAVING <having_condition>
7. SELECT
8. DISTINCT <select list>
9. ORDER BY <order_by_condition>
10. LIMIT <limit_number>
过程:
1、加载from子句的前两个表计算笛卡尔积,生成虚拟表vt1;
1、筛选关联表符合on表达式的数据,保留主表,生成虚拟表vt2;
3、如果使用的是外连接(LEFT/RIGHT/FULL OUTER JOIN),执行on的时候,会将主表中不符合on条件的数据也加载进来,做为外部行
4、如果from子句中的表数量大于2,则重复第一步到第三步,直至所有的表都加载完毕,更新vt3;
5、执行where表达式,筛选掉不符合条件的数据生成vt4;
6、执行group by子句。group by 子句执行过后,会对子句组合成唯一值并且对每个唯一值只包含一行,生成vt5,。一旦执行group by,后面的所有步骤只能得到vt5中的列(group by的子句包含的列)和聚合函数。
7、执行聚合函数,生成vt6;
8、执行having表达式,筛选vt6中的数据。having是唯一一个在分组后的条件筛选,生成vt7;
9、从vt7中筛选列,生成vt8;
10、执行distinct,对vt8去重,生成vt9。其实执行过group by后就没必要再去执行distinct,因为分组后,每组只会有一条数据,并且每条数据都不相同。
11、对vt9进行排序,此处返回的不是一个虚拟表,而是一个游标,记录了数据的排序顺序,此处可以使用别名;
12、执行limit语句,将结果返回给客户端