内连接外连接

SQL连接类型详解

内连接

内连接也叫连接,是最早的一种连接,最早被称为普通连接或自然连接。内连接是从结果中删除其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。

内连接的语法:

SELECT fieldlist

FROM table1 [INNER]join table2

ON table1.column=table2.column

一个表中的行和与另外一个表中的行匹配连接。表中的数据决定了如何对这些行进行组合。从每一个表中选取一行,根据这些列的值是否相同,组合方式分为一对一、多对一和多对多的关系。

1.一对一关系

当连接的两个表,两个连接列的值完全相同,则两个表连接相当于一对一的关系。

下面在“pubs”数据库中“titles”和“titleauthor”两个表中,根据相同列“title_id”进行内连接。在查询分析器中输入的SQL语句如下:

use pubs

select *

from   titles

innerjoin titleauthor

on   titles.title_id= titleauthor.title_id

实现的过程如图1所示。

 

图1内连接时一对一的关系

说明:表“titles”和“titleauthor”都是SQL Server自带的数据库“pubs”的表。由于两个表中的title_id列都是具有惟一值的索引,所以两个表的内连接属于一对一的关系。

2.多对一关系

当连接的两个表,其中一个表要连接的列出现重复值,另外一个表的值是惟一的。这时连接的两个表之间的出现了多对一的关系。

下面“student”表中的“学号”具有惟一值,而“grade”成绩表中的“学号”有重复值。现在实现这两个表的内连接。在查询分析器中输入的SQL语句如下:

use student

select *

from grade

joinstudent

on student.学号=grade.学号 

实现的过程如图2所示。

 


图2内连接时多对一的关系

3.多对多关系

当连接的两个表,要连接的列都出现重复值,这时连接的两个表之间出现多对多的关系。

本例是SQL Server自带的数据库“pubs”,其中的两个表“titles”和“roysched”中的“royalty”列都有重复值,现在实现这两个表的内连接。在查询分析器中输入的SQL语句如下:

use pubs

select *

from titles

innerjoin roysched

on titles.royalty=roysched.royalty 

实现的过程如图3所示。

 


图3内连接时多对多的关系

 


外连接则扩充了内连接的功能,会把内连接中删除表源中的一些保留下来,由于保留下来的行不同,把外连接分为左外连接、右外连接和全外连接这3种连接。

1.左外连接

左外连接保留了第一个表的所有行,但只包含第二个表与第一表匹配的行。第二个表相应的空行被放入NULL值。

左外连接的语法:

use student

SELECT fieldlist

FROM table1leftjointable2

ON table1.column=table2.column

下面把“student”表和“grade”表左外连接,第一个表“student”有不满足连接条件的行。在查询分析器中输入的SQL语句如下:

use student

select *

from student

leftjoin grade

on student.学号=grade.学号

实现的过程如图1所示。

 

2.右外连接

右外连接保留了第二个表的所有行,但只包含第一个表与第二个表匹配的行。第一个表相应空行被入NULL值。


右外连接的语法:

use student

SELECT fieldlist

FROM table1 rightjoin table2

ON table1.column=table2.column

下面把“grade”表和“course”表右外连接,第二个表“course”有不满足连接条件的行。在查询分析器中输入的SQL语句如下:

use student

select *

from grade

rightjoin course

on course.课程代号=grade.课程代号

实现的过程如图2所示。

 


图2右外连接

3.全外连接

全外连接会把两个表所有的行都显示在结果表中。

全外连接的语法:

use student

SELECT fieldlist

FROM table1 fulljoin table2

ON table1.column=table2.column

把“grade”表和“course”表实现全连接,两个表都有不满足连接条件的行。在查询分析器中输入的SQL语句如下:

use student

select * from

grade full

joincourse

on course.课程代号=grade.课程代号

实现的过程如图3所示。


 


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/LSSSSSS/archive/2010/10/02/5918618.aspx

<think>嗯,我现在需要了解数据库内连接外连接的区别以及它们在SQL中的使用方法。首先,我得回忆一下数据库课程里老师讲过的内容。记得老师提到过连接(JOIN)是用来合并两个或多个表的行,基于它们之间的关联字段。不过具体内连接外连接有什么不同,我有点模糊了。 内连接应该就是只返回两个表中匹配的行对吧?比如表A和表B,用内连接的话,结果只包含A和B中都存在的记录。那外连接的话,可能还包括不匹配的行?外连接又分为左外连接、右外连接和全外连接,对吗?左外连接会返回左表的所有行,即使右表中没有匹配的行,这时候右表的字段会用NULL填充。同样,右外连接是返回右表的所有行,左表没有匹配的部分用NULL。全外连接就是左右两边都包含,不管有没有匹配。 那具体在SQL中怎么写呢?内连接应该是使用INNER JOIN关键字,而外连接则是LEFT JOIN、RIGHT JOIN、FULL JOIN这些关键字。我记得语法大概是这样的: SELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.列 = 表2.列; 左外连接的话,用LEFT JOIN替换INNER JOIN,对吧?那如果表1的某行在表2中没有对应的行,结果中表2的那些列就会是NULL。右外连接同理,用RIGHT JOIN,全外连接是FULL OUTER JOIN,不过可能有些数据库不支持全外连接,比如MySQL以前版本不支持,现在不知道怎么样了。 不过有时候可能会看到使用WHERE子句来隐式地做内连接,比如: SELECT * FROM 表1, 表2 WHERE 表1.列 = 表2.列; 但这种写法是不是隐式内连接?而外连接必须显式使用JOIN关键字对吗? 应用场景方面,内连接适合需要两个表都有相关数据的情况,比如订单和订单详情,必须同时存在才需要关联。而外连接适合需要包含主表所有记录的情况,比如显示所有客户,即使他们没有订单,这时候用左连接,客户表在左边,订单表在右边。 不过可能会有一些特殊情况,比如多个表连接时的顺序影响结果,或者在使用外连接时过滤条件的位置对结果的影响。比如在左外连接中,如果把条件放在WHERE子句里,可能会过滤掉NULL的行,而放在ON后面则不会。这点需要注意。 另外,性能方面,外连接可能比内连接更消耗资源,因为需要处理更多的数据,但具体还要看数据库的优化和索引情况。 对了,可能还需要注意不同数据库系统对语法的支持情况。比如MySQLSQL Server、Oracle在实现外连接时是否有差异。比如旧版本的MySQL可能不支持全外连接,这时候可能需要用UNION来模拟。 总结一下,内连接外连接的主要区别在于是否包含不匹配的行,内连接只保留匹配的,外连接保留一边或两边的所有行,并用NULL填充缺失的部分。使用时根据需求选择,需要所有主表记录时用外连接,否则用内连接。</think>### 数据库内连接外连接的区别及用法 #### 一、核心区别 1. **内连接(INNER JOIN)** - **匹配原则**:仅返回两个表中**满足关联条件**的行。 - **示例**:表A(用户表)与表B(订单表)内连接时,仅显示有订单的用户。 - **数学表达**: $$ A \bowtie_{A.id=B.user\_id} B = \{ (a,b) \mid a \in A, b \in B, a.id = b.user\_id \} $$ 2. **外连接(OUTER JOIN)** - **分类**: - **左外连接(LEFT JOIN)**:返回左表全部行 + 右表匹配行(无匹配时右表字段为`NULL`)。 - **右外连接(RIGHT JOIN)**:返回右表全部行 + 左表匹配行(无匹配时左表字段为`NULL`)。 - **全外连接(FULL JOIN)**:返回左右表全部行(无匹配时对方字段为`NULL`)。 - **示例**:左外连接可展示所有用户(含未下单用户)及其订单。 #### 二、SQL语法对比 | 类型 | 语法示例 | 结果说明 | |---------------|-----------------------------------------------|------------------------------| | 内连接 | `SELECT * FROM A INNER JOIN B ON A.id=B.id` | 仅匹配行 | | 左外连接 | `SELECT * FROM A LEFT JOIN B ON A.id=B.id` | 左表全保留,右表补`NULL` | | 右外连接 | `SELECT * FROM A RIGHT JOIN B ON A.id=B.id` | 右表全保留,左表补`NULL` | | 全外连接[^1] | `SELECT * FROM A FULL OUTER JOIN B ON A.id=B.id` | 两表全保留,无匹配补`NULL` | #### 三、使用场景 1. **内连接**:需**精确匹配**的场景(如查询用户与订单详情)。 2. **左/右外连接**:需保留**主表完整数据**(如统计所有用户的订单,含未下单用户)。 3. **全外连接**:需合并两表所有记录(如数据对比或合并)。 #### 四、关键注意事项 1. **隐式内连接**:通过`WHERE`子句实现(`SELECT * FROM A,B WHERE A.id=B.id`),但可读性较差。 2. **条件位置影响结果**: - **外连接中**:过滤条件写在`ON`会保留主表所有行,写在`WHERE`会过滤`NULL`值。 3. **数据库兼容性**: - MySQL 8.0+支持全外连接,旧版本需用`UNION`模拟。 - SQL Server、Oracle均支持全外连接。 #### 五、示例对比 假设表`users`(用户)和`orders`(订单): ```sql -- 内连接:仅显示有订单的用户 SELECT users.name, orders.amount FROM users INNER JOIN orders ON users.id = orders.user_id; -- 左外连接:显示所有用户(含无订单者) SELECT users.name, orders.amount FROM users LEFT JOIN orders ON users.id = orders.user_id; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值