现象描述:
两个单独的表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的执行顺序到底是怎么样的?
两个单独的表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的执行顺序到底是怎么样的?
解决方案 »
- Oracle专家级提问
- 【面试题】某表定期删除之前的数据,求教该表设计要点
- 创建了oracle 函数,但是在 plsql的function中找不到,数据库中也没有这函数。
- 如何获得oracle中一个字符串中的一个字符
- oracle11g能连上oralcle817的服务器吗?
- dbms_job.remove()到底有什么用处?什么时候使用?
- 救救超菜鸟---对一备份文件如何下手啊?
- 请教一个ORACLE备份的问题。(急盼)
- 这个存储过程这么写对么
- Oracle 11g提供的自动增加分区功能可以指定分区名字吗?
- oracle中与||功能相同的是哪个?十个选择题,但记不清选项,有谁知道答案呢?谢谢大家!!!
- 在普通的PC机上,应该装哪个版本的ORACLE?
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、使用order by对结果集进行排序。
select * from(select * from customer order by CUSTOMER_ID DESC) where rownum<2rownum 是虛列,它總是從1開始的
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
具体看你的数据情况了
如果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过滤。
是这样吗?