Heim >Datenbank >MySQL-Tutorial >Oracle多表连接详解

Oracle多表连接详解

WBOY
WBOYOriginal
2016-06-07 15:20:091371Durchsuche

1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 3. 自连接(同一张表内的连接) SQL的标准语法: select table1. column ,table2. column from table1[ inner | left

 

1. 内连接(自然连接)

2. 外连接

(1)左外连接 (左边的表不加限制)

(2)右外连接(右边的表不加限制)

(3)全外连接(左右两表都不加限制)

3. 自连接(同一张表内的连接)

SQL的标准语法:

<ol>
<li><span><span>select</span><span> table1.</span><span>column</span><span>,table2.</span><span>column</span><span> </span></span></li>
<li>
<span>from</span><span> table1 [</span><span>inner</span><span> | </span><span>left</span><span> | </span><span>right</span><span> | </span><span>full</span><span> ] </span><span>join</span><span> table2 </span><span>on</span><span> table1.column1 = table2.column2; </span>
</li>
</ol>

inner join 表示内连接;
left join表示左外连接;
right join表示右外连接;
full join表示完全外连接;
on子句 用于指定连接条件。

注意:

如果使用from子句指定内、外连接,则必须要使用on子句指定连接条件;

如果使用(+)操作符指定外连接,则必须使用where子句指定连接条件。

一. 内连接(Inner Join/Join)

1.1  Inner Join

Inner join逻辑运算符返回满足第一个(顶端)输入与第二个(底端)输入联接的每一行。这个和用select查询多表是一样的效果,所以内连接用的很少。
还有一点要说明的就是Join 默认就是inner join。 所以我们在写内连接的时候可以省略inner 这个关键字。

1.2 下面举例来说明内连接:

1.2.1 先创建2张测试表并插入数据:

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave;  </span></span></li>
<li>
<span>ID  </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>1  dave  </span></li>
<li><span>2  bl  </span></li>
<li><span>1  bl  </span></li>
<li><span>2  dave  </span></li>
<li><span> </span></li>
<li><span> </span></li>
<li>
<span>SQL> </span><span>select</span><span> * </span><span>from</span><span> bl;  </span>
</li>
<li>
<span>ID  </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>1  dave  </span></li>
<li><span>2  bl </span></li>
</ol>

1.2.3 用内链接进行查询:

<ol>
<li><span><span>SQL> </span><span>Select</span><span> a.id,a.</span><span>name</span><span>,b.</span><span>name</span><span> </span><span>from</span><span> dave a </span><span>inner</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id=b.id;   </span><span>-- 标准写法 </span><span> </span></span></li>
<li>
<span>ID </span><span>NAME</span><span>       </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- </span><span> </span>
</li>
<li><span>1 dave       dave  </span></li>
<li><span>2 bl         bl  </span></li>
<li><span>1 bl         dave  </span></li>
<li><span>2 dave       bl  </span></li>
<li><span> </span></li>
<li><span> </span></li>
<li>
<span>SQL> </span><span>Select</span><span> a.id,a.</span><span>name</span><span>,b.</span><span>name</span><span> </span><span>from</span><span> dave a </span><span>join</span><span> bl b </span><span>on</span><span> a.id=b.id;  </span><span>-- 这里省略了inner 关键字 </span><span> </span>
</li>
<li>
<span>ID </span><span>NAME</span><span>       </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- </span><span> </span>
</li>
<li><span>1 dave       dave  </span></li>
<li><span>2 bl         bl  </span></li>
<li><span>1 bl         dave  </span></li>
<li><span>2 dave       bl  </span></li>
<li><span> </span></li>
<li><span> </span></li>
<li>
<span>SQL> </span><span>Select</span><span> a.id,a.</span><span>name</span><span>,b.</span><span>name</span><span> </span><span>from</span><span> dave a,bl b </span><span>where</span><span> a.id=b.id;  </span><span>-- select 多表查询 </span><span> </span>
</li>
<li>
<span>ID </span><span>NAME</span><span>       </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- </span><span> </span>
</li>
<li><span>1 dave       dave  </span></li>
<li><span>2 bl         bl  </span></li>
<li><span>1 bl         dave  </span></li>
<li><span>2 dave       bl </span></li>
</ol>

从这三个SQL 的结果我们也可以看出,他们的作用是一样的。

1.3 自然连接(Natural join)

自然连接是在两张表中寻找那些数据类型和列名都相同的字段,然后自动地将他们连接起来,并返回所有符合条件按的结果。

先看一下自然连接的例子:

<ol>
<li><span><span>SQL> </span><span>Select</span><span> id,</span><span>name</span><span> </span><span>from</span><span> dave a natural </span><span>join</span><span> bl b;  </span></span></li>
<li>
<span>ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>1 dave  </span></li>
<li><span>2 bl </span></li>
</ol>

这里我们并没有指定连接的条件,实际上oracle为我们自作主张的将,dave表中的id和name字段与bl表中的id和name字段进行了连接。也就是实际上相当于

<ol>
<li><span><span>SQL> </span><span>Select</span><span> dave.id,bl.</span><span>name</span><span> </span></span></li>
<li><span><span>From</span><span> dave </span><span>join</span><span> bl </span><span>on</span><span> dave.id = bl.id </span><span>and</span><span> dave.</span><span>name</span><span>=bl.</span><span>name</span><span>;  </span></span></li>
<li>
<span>ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>1 dave  </span></li>
<li><span>2 bl </span></li>
</ol>

因此,我们也可以将自然连接理解为内连接的一种。

有关自然连接的一些注意事项:

(1).如果做自然连接的两个表的有多个字段都满足有相同名称和类型,那么他们会被作为自然连接的条件。

(2).如果自然连接的两个表仅是字段名称相同,但数据类型不同,那么将会返回一个错误。

二. 外连接(Outer Join)

outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。外连接分为三种: 左外连接,右外连接,全外连接。 对应SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常我们省略outer 这个关键字。 写成:LEFT/RIGHT/FULL JOIN。

在左外连接和右外连接时都会以一张表为基表,该表的内容会全部显示,然后加上两张表匹配的内容。 如果基表的数据在另一张表没有记录。 那么在相关联的结果集行中列显示为空值(NULL)。

对于外连接, 也可以使用“(+) ”来表示。 关于使用(+)的一些注意事项:

1.(+)操作符只能出现在where子句中,并且不能与outer join语法同时使用。

2. 当使用(+)操作符执行外连接时,如果在where子句中包含有多个条件,则必须在所有条件中都包含(+)操作符

3.(+)操作符只适用于列,而不能用在表达式上。

4.(+)操作符不能与or和in操作符一起使用。

5.(+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。 

在做实验之前,我们先将dave表和bl里加一些不同的数据。 以方便测试。

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> bl;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>         1 dave  </span></li>
<li><span>         2 bl  </span></li>
<li><span>         3 big bird  </span></li>
<li><span>         4 exc  </span></li>
<li><span>         9 怀宁  </span></li>
<li>
<span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave;  </span>
</li>
<li>
<span>        ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>         8 安庆  </span></li>
<li><span>         1 dave  </span></li>
<li><span>         2 bl  </span></li>
<li><span>         1 bl  </span></li>
<li><span>         2 dave  </span></li>
<li><span>         3 dba  </span></li>
<li><span>         4 sf-express  </span></li>
<li><span>         5 dmm </span></li>
</ol>

2.1 左外连接(Left outer join/ left join)

left join是以左表的记录为基础的,示例中Dave可以看成左表,BL可以看成右表,它的结果集是Dave表中的数据,在加上Dave表和BL表匹配的数据。换句话说,左表(Dave)的记录将会全部表示出来,而右表(BL)只会显示符合搜索条件的记录。BL表记录不足的地方均为NULL.

示例:

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>left</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span></span></li>
<li>
<span>       ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>--------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>        1 bl                  1 dave  </span></li>
<li><span>        1 dave                1 dave  </span></li>
<li><span>        2 dave                2 bl  </span></li>
<li><span>        2 bl                  2 bl  </span></li>
<li><span>        3 dba                 3 big bird  </span></li>
<li><span>        4 sf-express          4 exc  </span></li>
<li>
<span>        5 dmm                             </span><span>-- 此处B表为null,因为没有匹配到 </span><span> </span>
</li>
<li>
<span>        8 安庆                             </span><span>-- 此处B表为null,因为没有匹配到 </span><span> </span>
</li>
<li><span> </span></li>
<li>
<span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>left</span><span> </span><span>outer</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span>
</li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li><span>         5 dmm  </span></li>
<li><span>         8 安庆  </span></li>
</ol>

用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在右表,左表就是全部显示,故是左连接。

<ol>
<li><span><span>SQL> </span><span>Select</span><span> * </span><span>from</span><span> dave a,bl b </span><span>where</span><span> a.id=b.id(+);    </span><span>-- 注意: 用(+) 就要用关键字where </span><span> </span></span></li>
<li>
<span>       ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li><span>         5 dmm  </span></li>
<li><span>         8 安庆  </span></li>
</ol>

2.2 右外连接(right outer join/ right join)

和left join的结果刚好相反,是以右表(BL)为基础的, 显示BL表的所以记录,在加上Dave和BL 匹配的结果。 Dave表不足的地方用NULL填充.

示例:

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>right</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li>
<span>                               9 怀宁    </span><span>--此处左表不足用Null 填充</span><span> </span>
</li>
</ol>

已选择7行。

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>right</span><span> </span><span>outer</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li>
<span>                               9 怀宁  </span><span>--此处左表不足用Null 填充</span><span> </span>
</li>
</ol>

已选择7行。  

用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在左表,右表就是全部显示,故是右连接。

<ol>
<li><span><span>SQL> </span><span>Select</span><span> * </span><span>from</span><span> dave a,bl b </span><span>where</span><span> a.id(+)=b.id;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li><span>                              9 怀宁  </span></li>
</ol>

2.3 全外连接(full outer join/ full join)

左表和右表都不做限制,所有的记录都显示,两表不足的地方用null 填充。 全外连接不支持(+)这种写法。

示例:

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>full</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         8 安庆  </span></li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li><span>         5 dmm  </span></li>
<li><span>                               9 怀宁 </span></li>
</ol>

已选择9行。

<ol>
<li><span><span>SQL> </span><span>select</span><span> * </span><span>from</span><span> dave a </span><span>full</span><span> </span><span>outer</span><span> </span><span>join</span><span> bl b </span><span>on</span><span> a.id = b.id;  </span></span></li>
<li>
<span>        ID </span><span>NAME</span><span>               ID </span><span>NAME</span><span> </span>
</li>
<li>
<span>---------- ---------- ---------- ---------- </span><span> </span>
</li>
<li><span>         8 安庆  </span></li>
<li><span>         1 dave                1 dave  </span></li>
<li><span>         2 bl                  2 bl  </span></li>
<li><span>         1 bl                  1 dave  </span></li>
<li><span>         2 dave                2 bl  </span></li>
<li><span>         3 dba                 3 big bird  </span></li>
<li><span>         4 sf-express          4 exc  </span></li>
<li><span>         5 dmm  </span></li>
<li><span>                               9 怀宁 </span></li>
</ol>

已选择9行。

三. 自连接

自连接(self join)是SQL语句中经常要用的连接方式,使用自连接可以将自身表的一个镜像当作另一个表来对待,从而能够得到一些特殊的数据。

示例:

在oracle的scott的schema中有一个表是emp。在emp中的每一个员工都有自己的mgr(经理),并且每一个经理自身也是公司的员工,自身也有自己的经理。

下面我们需要将每一个员工自己的名字和经理的名字都找出来。这时候我们该怎么做呢?

如果我们有两张这样的表分别教worker和mgr,那么我们就很好写SQL语句。

Select worker.name,

Mgr.name

From worker,mgr

Where worker.id = mgr.id;

但现在我们只有一张emp表。所以我们可以采用自连接。自连接的本意就是将一张表看成多张表来做连接。我们可以这样来写SQL语句:

<ol>
<li><span><span>SQL> </span><span>select</span><span> </span><span>work</span><span>.ename worker,mgr.ename  manager </span><span>from</span><span> scott.emp </span><span>work</span><span>, scott.emp mgr  </span></span></li>
<li>
<span>  2  </span><span>where</span><span> </span><span>work</span><span>.mgr = mgr.empno(+)  </span>
</li>
<li>
<span>  3  </span><span>order</span><span> </span><span>by</span><span> </span><span>work</span><span>.ename;  </span>
</li>
<li><span>WORKER     MANAGER  </span></li>
<li>
<span>---------- ---------- </span><span> </span>
</li>
<li><span>ADAMS      SCOTT  </span></li>
<li><span>ALLEN      BLAKE  </span></li>
<li><span>BLAKE      KING  </span></li>
<li><span>CLARK      KING  </span></li>
<li><span>FORD       JONES  </span></li>
<li><span>JAMES      BLAKE  </span></li>
<li><span>JONES      KING  </span></li>
<li>
<span>KING                                  </span><span>--此处右表不足用Null 填充 </span><span> </span>
</li>
<li><span>MARTIN     BLAKE  </span></li>
<li><span>MILLER     CLARK  </span></li>
<li><span>SCOTT      JONES  </span></li>
<li><span>SMITH      FORD  </span></li>
<li><span>TURNER     BLAKE  </span></li>
<li><span>WARD       BLAKE </span></li>
</ol>
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn