Oracle SQL语句执行顺序
(8)select (9) distinct
(1) from
(3) join
(2) on
(4) where
(5) group by
(6) with {cube | rollup}
(7) having
(10) order by
1、from:首先对from子句中的前两个表执行一个笛卡尔乘积(选择相对小的表做基础表),生成虚拟表 vt1
2、on: 对 vt1 应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行被插入到 tv2
3、outer (join):如果指定了outer join(相对于cross join或inner join),left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3 。如果from子句包含两个以上的表,那么就将 vt3 和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3
4、where:对 tv3 应用where筛选器,只有使为true的行才插入 tv4
5、group by:按 group by 子句中的列列表对 tv4 中的行进行分组,生成 tv5
6、cute|rollup:把超组插入vt5,生成 vt6
7、having:对 vt6 应用having筛选器,只有使为true的组插入到 vt7
8、select:处理select列表,产生 vt8
9、distinct:将重复的行从 vt8 中删除,产品 vt9
注意:
如果用了group by子句,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的,那么distinct是多余的
10、order by:将 vt9 中的行按 order by 子句排序,生成一个游标 vc10,而不是虚拟表。在这一步中是第一个也是唯一一个可以使用 select列表中别名 的步骤。
注意:
10.1、sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。
10.2、正因为返回值是游标,那么使用order by 子句查询不能应用于表达式。
10.3、排序是很需要成本的,除非你必须要排序,否则最好不要指定order by
11、应用top选项。此时才返回结果给请求者即用户;
每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句,将跳过相应的步骤。
参考:
SQL语句执行顺序
Oracle SQL语句执行流程与顺序原理详解
关于sql和MySQL的语句执行顺序(必看!!!)