create or replace view v1 as select ename,job,sal from emp where deptno = 30;
create or replace view v2 as select ename,job,sal from emp;
-- 查找两个表中匹配的行
/*使用内连接*/
select v1.* from v1,v2 where v1.ename=v2.ename and v1.job=v2.job and v1.sal=v2.sal
/*使用半连接*/
select * from v1 where (ename,job,sal) in (select ename,job,sal from v2)
/*使用intersect函数*/
SQL> select * from v2
2  intersect
3  select * from v1;
ENAME      JOB              SAL
---------- --------- ----------
ALLEN      SALESMAN        1600
BLAKE      MANAGER         2850
JAMES      CLERK            950
MARTIN     SALESMAN        1250
TURNER     SALESMAN        1500
WARD       SALESMAN        1250
6 rows selected.
-- 查找两个表中不匹配的行
/*使用半连接,使用not in需要注意null值的问题*/
SQL> select * from v2 where (ename,job,sal) not in (select ename,job,sal from v1);
ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            800
JONES      MANAGER         2975
CLARK      MANAGER         2450
SCOTT      ANALYST         3000
KING       PRESIDENT       5000
ADAMS      CLERK           1100
FORD       ANALYST         3000
MILLER     CLERK           1300
8 rows selected.
/* 使用minus函数, 注意表的先后顺序 */
SQL> select * from v2 minus select * from v1;
ENAME      JOB              SAL
---------- --------- ----------
ADAMS      CLERK           1100
CLARK      MANAGER         2450
FORD       ANALYST         3000
JONES      MANAGER         2975
KING       PRESIDENT       5000
MILLER     CLERK           1300
SCOTT      ANALYST         3000
SMITH      CLERK            800
8 rows selected.
/* 使用not in 的空值处理 */
create table emp1 (deptno number);
insert into emp1 values (10);
insert into emp1 values (20);
insert into emp1 values (50);
insert into emp1 values (null);
/* 下面查询返回结果为空 */
SQL> select deptno from dept where deptno not in (select deptno from emp1);
no rows selected
/* 解决方法一:添加is not null 条件 */
SQL> select deptno from dept where deptno not in (select deptno from emp1 where deptno is not null);
DEPTNO
----------
30
40
/* 解决方法二:使用相关连子查询,下面两个语句可以使用左外连接改写,见最后 */
SQL> select deptno from dept where not exists (select null from emp1 where dept.deptno=emp1.deptno);
DEPTNO
----------
30
40
SQL> select deptno from dept where deptno not in (select deptno from emp1 where emp1.deptno=dept.deptno);
DEPTNO
----------
30
40
/* 解决方法三:在字段上添加非空约束,这个需要根据实际业务需求处理 */
/* 返回dept在emp表中不匹配的记录,要求返回部门的所有信息 */
SQL> select * from dept where deptno not in (select deptno from emp where deptno is not null);
DEPTNO DNAME          LOC
---------- -------------- -------------
40 OPERATIONS     BOSTON
/* 上面的反连接可以使用做外连接改写 */
SQL> select dept.* from dept left join emp on dept.deptno=emp.deptno where emp.deptno is null;
DEPTNO DNAME          LOC
---------- -------------- -------------
40 OPERATIONS     BOSTON
SQL>