SQL的一个明显特征是解析代码的顺序。在大数语言中,代码按编码顺序被处理,但是在SQL语言中,顺序却并非如此,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理。
每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对外部查询不可见。只是最后一步生成的表才会返回给调用者。
一个查询SQL语句:
(7)SELECT (8)DISTINCT (10)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2) ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)HAVING <having_condition>
(9)ORDER BY <order_by_list>
具体的解析过程:
1-From | 对2张表执行笛卡尔集,生成虚拟表 VT1 |
2-On | 对VT1表中符合On 条件的记录组合成虚拟表VT2 |
3-Join | 如果指定了该选项,那么在VT2基础之上,加入剩余表的记录,组合虚拟表VT3 |
4-Where | 条件筛选,在VT3基础上,筛选出符合条件记录生成VT4 |
5-Group By | 按照group by指定的列对VT4进行分组,生成虚拟表VT5 |
6-Having | 对VT5应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT6 |
7-Select | 对VT6的列进行筛选,生成VT7 |
8-Distinct | 对VT7中按Distinct指定删除重复的行 生成VT8 |
9-Order by | 将VT8按照指定的顺序排列生成 游标 |
10-Top | 对9生成游标,选定指定数目或比例的记录,返回给调用者 |
按ORDER BY子句中的列列表排序上步返回的行,返回游标VC10.这一步是第一步也是唯一一步可以使用SELECT列表中的列别名的步骤。这一步不同于其它步骤的 是,它不返回有效的表,而是返回一个游标。
因为这一步不返回表,使用了ORDER BY子句的查询不能用作表表达式。表表达式包括:视图、内联表值函数、子查询、派生表和共用表达式。它的结果必须返回给期望得到物理记录的客户端应用程序。
——以下表达式将出错 order by语句不返回实际表
select *
from(select orderid,customerid from orders order by orderid)
as d
总结起来,SQL查询语句的执行顺序
(1).FROM 子句, 组装来自不同数据源的数据
(2).WHERE 子句, 基于指定的条件对记录进行筛选
(3).GROUP BY 子句, 将数据划分为多个分组
(4).使用聚合函数进行计算
(5).使用 HAVING 子句筛选分组
(6).计算所有的表达式
(7).使用 ORDER BY 对结果集进行排序