您的位置:首页 > 数据库 > Oracle

深入了解ORACLE连接:JION,LEFT JION RIGHT JION FULL JION 联系与区别

2017-12-26 18:26 751 查看
  转自 http://blog.csdn.net/yuxuan1215/article/details/8892538


1、概述

连接是(JOIN) 是根据两个或者多个表之间的列建立关系, 获取所需要的数据,在Oracle数据库中,提供了自连接也称内连接(inner join或者join),自然连接(natural join),左连接(left join或者left outer join ),右连接(right join或者 right outer join),全连接(full join或者 full outer join)以及笛卡尔积(cross join)

基本语法:select table1.column,table2.column from table1 [inner | left | right | full ] join table2 on table1.column1 = table2.column2;

为了更好的再后面阐述:我们首先建立了stu以及class两张表如下:

STU表如下:

create table stu(
stu_id varchar2( 10),
name varchar2(10 ),
class_id varchar( 10)
);


STU表中数据为:



CLASS创建如下:
create table class(
class_id varchar2( 10),
class_name varchar2( 10)
);


数据有:




2、Oracle连接


2.1、内连接(inner jion)

Oracle 的join连接默认就是inner join,所以在写内连接时可以把inner省略, 这种连接返回的是两表交集的部分,即如果表中至少有一行匹配则但会行。可以用下面蓝色部分表示:



我们用实例来说明什么是内连接,我们可以在表stu和表class 通过class_id建立连接如下,下面三种方式是等价的:
select s.stu_id,s.name,s.class_id,c.class_name from stu s, class c where s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s inner join class c on s.class_id =c.class_id order by stu_id ;


我们可以看到结果返回的是两表中class_id相同的那些记录:



用inner jion中我们是根据两表中的class_id字段来匹配,还有一种连接可以根据量表自动去匹配相同的字段,并返回数据行,这种连接称作 自然连接(natural join),我们可以把它看成是内连接的一种,用法如下:
select stu_id,name ,class_id,c.class_name from stu s natural join   class c


 自然连接需要注意一下亮点:

  1、如果自然连接的多个字段的名称和类型都匹配,那么他们都会作为自然连接的连接条件;

  2、若自然连接的连个表仅字段相同,但是类型不同将会返回一个错误。


2.2、外连接

在Oracle中外连接主要有 左外连接、右外连接以及全连接三种


2.2.1、左外连接(left join或者left outer join)

左外连接:返回的记录行数与左表相同,即使右表中没有匹配行,也从左表中返回所有行;如下图所示:



在oracle中,我们可以建立左连接如下,以下这三种方式建立的左连接时等价的:

select s.stu_id,s.name,s.class_id,c.class_name from stu s left join class c on s.class_id =c.class_id order by  stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s left outer join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s ,class c where s.class_id =c.class_id(+) order by stu_id;


 返回记录行如下,从返回结果中可以看出左连接返回了stu的所有行,如class表中无数据的字段则为null



说明:

1、使用(+)建立左连接时,只能在where 条件中使用,且(+)要放在右表后

2、当使用(+)建立左连接时,如果where 有多个条件那么所有的条件都要加上(+)

3、 (+)只使用列,不适合用在表达式上

4、(+)不能和in、not in 以及 or 操作符一起使用

5、(+)只适用左连接和右连接,不能实现全连接, 但是可以通过 左连接 UNION 右连接实现。

2.2.2、右连接(right join或者right outer join)

右连接会返回右表中的所有行,即使左表中没有匹配行,也返回右表的所有行,如下图所示:



类似左连接,在oracle中实现右连接有一下几种方式,它们亦是等价的:
select s.stu_id,s.name,s.class_id,c.class_name from stu s right join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s right outer join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id(+) =c.class_id order by stu_id ;


返回的记录行是如下, 返回结果中可以看出左连接返回了class的所有行,如stu表中无数据的字段则为null



说明:当用(+)表示右连接时,说明基本和左连接一样,只是(+)需要用在左表的字段上 。

2.2.3、全连接(full join 或者full outer join)

全连接:返回的是两表的全集,无论匹配不匹配都返回行,如下图所示:



在oracle实现全连接的方式如下,下面这两种方式是等价的:
select s.stu_id,s.name,s.class_id,c.class_name from stu s full join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s full outer join class c on s.class_id =c.class_id order by stu_id ;


返回的记录行如下,两表中没匹配且在其中一张表无数据,返回null



说明:全连接不能用(+)表示,但是可以用左连接 UNION 右连接表示,注意:使用的不是UNION ALL( 请参考UNION
与UNION的区别 )
select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id =c.class_id(+)
union
select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id(+) =c.class_id order by stu_id ;


2.3、笛卡尔积(cross join)

笛卡尔积 :返回的是两表的乘积,返回的行数为两表各自行数的乘积,使用方法如下:
select s.stu_id,s.name,s.class_id,c.class_name from stu s cross join   class c


 可以得到返回的记录为:



补充 :

还有一种oracle并没有关键字的连接,用使用等值以外的条件作为连接条件,可以表示如下:

select stu_id,name ,c.class_name from stu s , class c  where s.class_id !=c.class_id





3、总结

可以把以上各个连接用一张图表示(这张图是引用别人的博客,具体博客地址没找到,对原作者十分抱歉)



把之前的sql也整理如下:

--jion inner join
select s.stu_id,s.name,s.class_id,c.class_name from stu s,class c where s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s inner join class c on s.class_id =c.class_id order by stu_id ;

-- left jion
select s.stu_id,s.name,s.class_id,c.class_name from stu s left join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s left outer join class c on s.class_id =c.class_id order by stu_id ;
select s.stu_id,s.name,s.class_id,c.class_name from stu s ,class c where s.class_id =c.class_id(+) order by stu_id ;
--right jion
select s.stu_id,s.name,s.class_id,c.class_name from stu s right join class c on s.class_id =c.class_id order by stu_id ; select s.stu_id,s.name,s.class_id,c.class_name from stu s right outer join class c on s.class_id =c.class_id order by stu_id ; select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id(+) =c.class_id order by stu_id ;
--full jion
select s.stu_id,s.name,s.class_id,c.class_name from stu s full join class c on s.class_id =c.class_id order by stu_id ; select s.stu_id,s.name,s.class_id,c.class_name from stu s full outer join class c on s.class_id =c.class_id order by stu_id ;

select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id =c.class_id(+) union select s.stu_id,s.name,s.class_id,c.class_name from stu s , class c where s.class_id(+) =c.class_id order by stu_id ;

--cross jion
select s.stu_id,s.name,s.class_id,c.class_name from stu s cross join class c
--natural join
select stu_id,name ,class_id,c.class_name from stu s natural join class c
--补
select stu_id,name ,c.class_name from stu s , class c where s.class_id !=c.class_id
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: