exists和not exists的使用

来源:互联网 发布:discuz 标签 seo 编辑:程序博客网 时间:2024/05/19 12:27
 2.1. exists的使用

  Exists 用于只能用于子查询,可以替代in,若匹配到结果,则退出内部查询,并将条件标志为true,传回全部结果资料,in 不管匹配到匹配不到都全部匹配完毕,使用exists 可以将子查询结果定为常量,不影响查询效果,而且效率高。如查询所有销售部门员工的姓名,对比如下:

  IN is often better if the results of the subquery are very small

  When you write a query using the IN clause, youre telling the rule-based optimizer that you want the inner query to drive the outer query.

  When you write EXISTS in a where clause, youre telling the optimizer that you want the outer query to be run first, using each value to fetch a value from the inner query.

  In many cases, EXISTS is better because it requires you to specify a join condition, which can invoke an INDEX scan. However, IN is often better if the results of the subquery are very small. You usually want to run the query that returns the smaller set of results first.

  In和exists对比:

  若子查询结果集比较小,优先使用in,若外层查询比子查询小,优先使用exists。因为若用in,则oracle 会优先查询子查询,然后匹配外层查询,若使用exists,则oracle 会优先查询外层表,然后再与内层表匹配。最优化匹配原则,拿最小记录匹配大记录。

  使用in

  select last_name, title

  from s_emp

  where dept_id in

  (select id

  from s_dept

  where name=Sales);

  使用exists

  select last_name,title

  from s_emp e

  not exists的使用

  与exists 含义相反,也在子查询中使用,取出不满足条件的,与not in有一定的区别,注意有时候not exists不能完全替代not in。如查询不在销售部的员工姓名

  select last_name,title

  from s_emp e

  where not exists

  (select x --把查询结果定为constant,提高效率

  from s_dept s where s.id=e.dept_id and s.name=Sales);

  not exists和not in不同的情况:

  drop table test1;

  drop table test2;

  create table test1(a number,b number);

  create table test2(a number,b number);

  insert into test1 values(1,1);

  insert into test1 values(1,2);

  insert into test2 values(1,1);

  insert into test2 values(1,null);

  --使用not exists找出test1不在test2中的记录,都用b字段匹配

  --返回结果1,2

  select * from test1 t1

  where not exists

  (select 1 from test2 t2 where t1.b=t2.b);

  --使用not in,没有结果返回,因为test2中的b有null

  select * from test1 t1 where t1.b not in (select t2.b from test2 t2);

  --用相关子查询,结果同not exists

  select * from test1 t1 where t1.b not in (select t2.b from test2 t2 where t1.b=t2.b);