sql外连接

这里有一个sql语句1

1、

select t1.* , t2.* from test t1 , test2 t2 where t1.cnum=t2.cnum (+) and t2.cnum>10  


这是关于t1和t2的一个左外链接。左外连接意味着,将符合条件的集合与t1表中未被选中的记录(并扩展到t2的所有字段取值为null)合并起来,

就是查询结果。到这似乎意味着,只要t1表中有记录,那么查询结果肯定不应该为空。上述语句似乎等效于sql语句2

2、

select t1.* ,t2.* from test t1, ( select test2.* from test2 where cnum>10) t2 where t1.cnum=t2.cnum(+)


实际上这个想法是错误的。实际上,那么不涉及外链接的条件子句(没有带“(+)”, 例如 t2.cnum>10 ),是在先执行完外链接后再执行不涉及外连接的条件子句进行过滤。

所以,实际上有可能所有结果都未通过过滤,而得到一个空集。

这时我们发现,这种情况与内连接是不同的。在使用内连接时,下面的sql语句3和4是等效的

3、

select t1.* ,t2.* from test t1 , test2 t2 where t1.cnum=t2.cnum  and t2.cnum>10


 

4、
select t1.* ,t2.* from test t1, ( select test2.* from test2 where cnum>10) t2 where t1.cnum=t2.cnum


另外,关于多个表连接中出现带“(+)”的条件子句时,需要注意一下情况:

1)(+)只能出现在两个不同表的列之间做比较的条件语句中,一列和常数比较的子句不能用(+)

2)(+)不能同时在一个谓词的左右两侧

3)(+)可以出现在多个条件子句中,但不同子句中(+)所跟的表不能相同。也就是说下面语句5是非法的,6、7是合法

5、

select * from test  t1, test2 t2,test3 t3 where t1.cnum=t2.cnum(+) and t3.cnum=t2.cnum(+)


6、

select * from test  t1, test2 t2,test_f t3 where t1.cnum=t2.cnum(+) and t2.cnum=t3.cnum(+)


 

7、
select * from test  t1, test2 t2,test_f t3 where t1.cnum=t2.cnum(+) and t1.cnum=t3.cnum(+)


4)or 或者 in 连接的条件子句中不能出现(+)

 

看来(+)只能表达部分外连接,复杂的还要靠outer join on 配合子查询来做。

你可能感兴趣的:(JOIN,sql,null,扩展)