这里有一个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
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(+)
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 配合子查询来做。