现象描述:
两个单独的表DEPT(主键字段为DEPT_ID,number类型),CUSTOMER(主键字段为CUSTOMER_ID,varchar类型)
要求不使用子查询,获取主键字段最大的一条记录。
1)对于表DEPT,使用SELECT * FROM DEMO_DEPT  WHERE (ROWNUM<2 )  ORDER BY DEPT_ID DESC,可以获取正确结果。
个人分析:先执行ORDER BY子句,然后再执行WHERE,所以可以获取DEPT_ID最大的记录。
2)对于表CUSTOMER,使用类似的SQL: select *  from customer  WHERE (ROWNUM<2 ) ORDER BY CUSTOMER_ID DESC,却不能获取正确的结果。
个人分析:与前面的恰好相反,先执行WHERE子句,然后再执行ORDER BY,所以(当然,排序字段是字符类型,即使先执行排序,也不一定能得到正确结果)问题:出现前面相矛盾的现象,那么SQL的执行顺序到底是怎么样的?

解决方案 »

  1.   

    1、from子句组装来自不同数据源的数据;
    2、where子句基于指定的条件对记录行进行筛选; 
    3、group by子句将数据划分为多个分组; 
    4、使用聚集函数进行计算;
    5、使用having子句筛选分组; 
    6、计算所有的表达式; 
    7、使用order by对结果集进行排序。
      

  2.   


    select * from(select *  from customer order by CUSTOMER_ID DESC) where rownum<2rownum 是虛列,它總是從1開始的 
      

  3.   

    表DEPT(主键字段为DEPT_ID,number类型),所以order by DEPT_ID desc是可以的:
    select * from(select *  from DEPTorder by DEPT_ID DESC) where rownum<2CUSTOMER(主键字段为CUSTOMER_ID,varchar类型),order by CUSTOMER_ID desc不一定可行。
    就看CUSTOMER_ID是怎么样的字符串,将其转换成统一格式,再order by,如:
    select * from(select *  from customer order by (lpad(CUSTOMER_ID,10,'0') DESC) where rownum<2
    具体看你的数据情况了
      

  4.   

    select * from customer  WHERE (ROWNUM<2 )  ORDER BY CUSTOMER_ID DESC
    如果CUSTOMER_ID为主键,将默认在该字段上建立唯一索引,所以查询的时候是
    Plan
    SELECT STATEMENT  ALL_ROWSCost: 2  Bytes: 48  Cardinality: 1  
    3 COUNT STOPKEY  
    2 TABLE ACCESS BY INDEX ROWID TABLE J2YD_DEMO.CUSTOMER Cost: 2  Bytes: 96  Cardinality: 2  
    1 INDEX FULL SCAN DESCENDING INDEX (UNIQUE) J2YD_DEMO.CUSTOMER_PK Cost: 1  Cardinality: 1  
    所以会先执行order by子句;
    如果CUSTOMER_ID不是主键,则会进行全表扫描,所以会先执行where过滤。
    是这样吗?