sql 语句的执行顺序

来源:互联网 发布:linux 用户环境变量 编辑:程序博客网 时间:2024/06/05 05:07

     首先要明白一点就是SQL 的语法顺序和执行顺序是不一致的

SQL的语法顺序:

    select   【distinct】 ....from ....【xxx  join】【on】....where....group by ....having....【union】....order by......

SQL的执行顺序:

   from ....【xxx  join】【on】....where....group by ....avg()、sum()....having....select   【distinct】....order by......


这回你知道where 或group by 直接使用select语句中的别名就会报错了吧,但在某些情况下在group by子句中间接使用别名不会报错

情况一:将表达式都写入group by 子句

select case when ta.call_time = 0 then 0      when ta.call_time <= 6 and ta.call_time > 0 then 1      when ta.call_time <= 60 and ta.call_time > 6 then 2      when ta.call_time <= 3600 and ta.call_time > 60 then 3      else 4 end as callt,        count(ta.annoyanceid) as counts   from t_annoyance ta  group by (case when ta.call_time = 0 then 0      when ta.call_time <= 6 and ta.call_time > 0 then 1      when ta.call_time <= 60 and ta.call_time > 6 then 2      when ta.call_time <= 3600 and ta.call_time > 60 then 3      else 4 end);  --group by 后面的就相当于callt;

情况二:将表达式放入子查询里

selectt1.callt, count(t2.annoyanceid) as counts
  from (select(case
                 when ta.call_time = 0 then 0
                 when ta.call_time <= 6 and ta.call_time > 0 then 1
                 when ta.call_time <= 60 and ta.call_time > 6 then 2
                 when ta.call_time <= 3600 and ta.call_time > 60 then 3
                 else 4
                end) as callt,
               ta.annoyanceid
          from t_annoyance ta) t1,
       t_annoyance t2
 where t1.annoyanceid = t2.annoyanceid
 group by t1.callt;
/* ----------------------------------------------------------------------------------------------------------------------------------------------------*/

from 子句--执行顺序为从后往前、从右到左
表名(最后面的那个表名为驱动表,执行顺序为从后往前, 所以数据量较少的表尽量放后)

oracle 的解析器按照从右到左的顺序处理,FROM 子句中的表名,FROM 子句中写在最后的表(驱动表 driving table)将被最先处理,即最后的表为驱动表,在FROM 子句中包含多个表的情况下,你最好选择记录条数最少的表作为驱动表。如果有3 个以上的表连接查询, 那就需要选择交叉表(intersection table)作为驱动表, 交叉表是指被其他表所引用的表多表连接时,使用表别名作用于每个列上,以减少解析时间并减少那些由列歧义引起的语法错误.

/* ----------------------------------------------------------------------------------------------------------------------------------------------------*/

where子句--执行顺序为自下而上、从右到左

ORACLE 采用自下而上从右到左的顺序解析Where 子句, 将可以过滤掉大量数据的条件写在where的子句的末尾性能最优

/* ----------------------------------------------------------------------------------------------------------------------------------------------------*/

 group by 和order by 子句执行顺序都为从左到右

select子句--少用*号,尽量取字段名称

ORACLE 在解析的过程中, 会将依次转换成所有的列名, 这个工作是通过查询数据字典完成的,

 使用列名意味着将减少消耗时间。

sql 语句用大写,因为 oracle 总是先解析 sql 语句,把小写的字母转换成大写的再执行


/*having 子句----很耗资源,尽量少用避免使用HAVING 子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作.如果能通过Where 子句在GROUP BY前限制记录的数目,那就能减少这方面的开销.(非oracle 中)on、where、having 这三个都可以加条件的子句中,on 是最先执行,where 次之,having 最后,因为on 是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where 也应该比having 快点的,因为它过滤数据后才进行sum,在两个表联接时才用on 的,所以在一个表的时候,就剩下where 跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where 可以使用rushmore 技术,而having 就不能,在速度上后者要慢。如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,where 的作用时间是在计算之前就完成的,而having 就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on 比where 更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where 进行过滤,然后再计算,计算完后再由having 进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里。*/


原创粉丝点击