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表中数据为:
Image may be NSFW.
Clik here to view.
Clik here to view.

Image may be NSFW.
Clik here to view.
Clik here to view.
.png)
CLASS创建如下:
create table class( class_id varchar2( 10), class_name varchar2( 10) );
数据有:
Image may be NSFW.
Clik here to view.
Clik here to view.
.png)
Image may be NSFW.
Clik here to view.
Clik here to view.

2、Oracle连接
2.1内连接(inner jion)
Oracle 的join连接默认就是inner join,所以在写内连接时可以把inner省略, 这种连接返回的是两表交集的部分,即如果表中至少有一行匹配则但会行。可以用下面蓝色部分表示:
Image may be NSFW.
Clik here to view.
Clik here to view.

Image may be NSFW.
Clik here to view.
Clik here to view.

我们用实例来说明什么是内连接,我们可以在表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相同的那些记录:
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Clik here to view.

Image may be NSFW.
Clik here to view.
.png)
用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)
左外连接:返回的记录行数与左表相同,即使右表中没有匹配行,也从左表中返回所有行;如下图所示:
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Clik here to view.
.png)
Clik here to view.

在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
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Clik here to view.
.png)
Clik here to view.

说明:
1、使用(+)建立左连接时,只能在where 条件中使用,且(+)要放在右表后
2、当使用(+)建立左连接时,如果where 有多个条件那么所有的条件都要加上(+)
3、(+)只使用列,不适合用在表达式上
4、(+)不能和in、not in 以及 or 操作符一起使用
5、(+)只适用左连接和右连接,不能实现全连接, 但是可以通过 左连接 UNION 右连接实现。
2.2.2右连接(right join或者right outer join)
右连接会返回右表中的所有行,即使左表中没有匹配行,也返回右表的所有行,如下图所示:
Image may be NSFW.
Clik here to view.
Clik here to view.

Image may be NSFW.
Clik here to view.
Clik here to view.
.png)
类似左连接,在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
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
.png)
说明:当用(+)表示右连接时,说明基本和左连接一样,只是(+)需要用在左表的字段上。
2.2.3 全连接(full join 或者full outer join)
全连接:返回的是两表的全集,无论匹配不匹配都返回行,如下图所示:
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
.png)
在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
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
.png)
说明:全连接不能用(+)表示,但是可以用左连接 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
可以得到返回的记录为:
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
.png)
补充:
还有一种oracle并没有关键字的连接,用使用等值以外的条件作为连接条件,可以表示如下:
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
.png)
select stu_id,name ,c.class_name from stu s , class c where s.class_id !=c.class_idImage may be NSFW.
Clik here to view.
3总结
可以把以上各个连接用一张图表示(这张图是引用别人的博客,具体博客地址没找到,对原作者十分抱歉)
Image may be NSFW.
Clik here to view.![]()
Clik here to view.
把之前的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
作者:yuxuan1215 发表于2013-5-6 21:56:43 原文链接
阅读:19 评论:0 查看评论