很多时候,我们使用左连接或者右连接都是为了简单的匹配我们需要连接的某张表里对应的数据
简单是因为只有一个约束条件,类似于a.id=b.id(+)的写法。但当我们需要对表添加多重约束的时候
可能会出现一些问题,如:造成左连接中左边数据的丢失或右连接中右边数据的丢失。
接下来就对这一问题进行讲解。
存在两张表 。
dept表
create table dept
(
deptno int primary key, --部门编号
dname nvarchar(30),--部门名称
loc nvarchar(30) --地址
)
emp表
create table emp
(
empno int primary key,--雇员编号
ename nvarchar(30),--雇员姓名
job nvarchar(30),--雇员职务
mgr int,--雇员上级编号
hiredate datetime,--雇佣日期
sal numeric(10,2),--薪水
comm numeric(10,2),--奖金
deptno int foreign key references dept(deptno) --因为deptno我们根据需要做成外键
)
例如:以左连接为例,如果我们只是想简单的根据雇员所在部门的编号查询部门名称。
那么我们只需要简单的这样写
select empno,ename,job,deptno,dname from emp left join dept on emp.deptno=dept.deptno;
--或者这样写
select empno,ename,job,deptno,dname from emp,dept where emp.deptno=dept.deptno(+);
但是当左连接中有多个条件约束条件,那该怎么办呢?
在上例中,如果我想再加一个条件dept中的loc为'Madrid'.
则用left join可以这样写
select empno,ename,job,deptno,dname from emp left join dept on emp.deptno=dept.deptno and dept.loc='Madrid';--没问题
很多人在用+写法的时候会这样写
select empno,ename,job,deptno,dname from emp,dept where emp.deptno=dept.deptno(+) and dept.loc='Madrid';--有问题
这种写法会造成的问题是:在dept表中,如果没有与dept表中deptno对应的emp表数据也会消失,约束条件就和emp.deptno=dept.deptno一样了。
这样显然是不正确的。
如果想使用左连接,同时又想增加'='右边表的多重约束,有两种办法。
一是再加上右表限制的同时也需要添加(+),如where emp.deptno=dept.deptno(+) and dept.loc(+)='Madrid'
二是在from中就将右边的表中的数据进行筛选,from emp,(select * from dept where dept.loc='Madrid') dt where emp.deptno=dt.deptno(+)
而对左连接等号左边的表(如上面说的emp表)字段的约束条件则没有这些要求,其他的外连接和左连接类似。
总结:
对于外连接, 也可以使用“(+) ”来表示。 关于使用(+)的一些注意事项:
1.(+)操作符只能出现在where子句中,并且不能与outer join语法同时使用。
2. 当使用(+)操作符执行外连接时,如果在where子句中包含有多个条件,则必须在所有条件中都包含(+)操作符
3.(+)操作符只适用于列,而不能用在表达式上。
4.(+)操作符不能与or和in操作符一起使用。
5.(+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。