SQL语句——12、exists 和 with

exists查询

使用EXISTS语句可以测试集合是否为空,EXISTS语句通常与子查询结合在一起使用。只要子查询中至少返回一个值,则EXISTS语句的值就为True,查到就不再继续查。

例如:找出领导(此员工的empno在mgr列存在即是领导

select empno,ename,mgr from emp e where exists (select 1 from emp where mgr=e.empno);

EMPNO ENAME MGR
---------- ---------- ----------
7902 FORD 7566
7698 BLAKE 7839
7839 KING
7566 JONES 7839
7788 SCOTT 7566
7782 CLARK 7839

6 rows selected.

 

in也能做到,只是in的效率不高,in会一直比下去,而exists对比成功就不在继续。

取反

 

用in改写时并不一定得到和not exists一致的结果。

例如:查找普通员工,即不是领导的人

SQL> select empno,ename from emp e where not exists (select 1 from emp where mgr=e.empno);

EMPNO ENAME
---------- ----------
7844 TURNER
7521 WARD
7654 MARTIN
7499 ALLEN
7934 MILLER
7369 SMITH
7876 ADAMS
7900 JAMES

8 rows selected.

 

而如果使用not in

SQL> select empno,ename from emp e where empno not in (select mgr from emp);

no rows selected

因为mgr字段中有null.而not in 等价于<>,从而<>null是一个永假的(或者说null不参与运算和比较)

with 语句 

当查询中多次用到某一部分时,可以用with语句创建一个公共临时表空间。因为子查询在内存临时表空间中,避免了重复解析,所以执行效率会提高不少。临时表在一次查询结束自动清除。

语法:

with
alias_name1 as (subquery1),
alias_name2 as (subQuery2),
……,
alias_nameN as (subQueryN)
select col1,col2…… col3
from alias_name1,alias_name2……,alias_nameN

 

例子:

SQL> with
q1 as (select 3+5 s from dual),
q2 as (select 3*5 m from dual),
q3 as (select s,m,s+m,s*m from q1,q2)
select * from q3;

S M S+M S*M
---------- ---------- ---------- ----------
8 15 23 120

with子句中的视图叫做询问块,询问块的复杂查询在with子句中只运行一次,运行成功后会将询问块的结果集保存到temp表空间,以后再次调用询问块时会在后台转换为对结果集的直接访问。

你可能感兴趣的:(SQL语句——12、exists 和 with)