外连接(左连接和右连接)

本文介绍了数据库查询中的内连接和外连接概念,强调了它们的区别。内连接主要返回两个表中匹配的记录,而外连接则包含所有记录,左连接以左表为主,右连接以右表为主。例如,右连接会显示dept表的所有数据并匹配员工信息,而左连接反之。外连接的查询结果条数通常多于内连接。示例展示了如何使用SQL进行左连接和右连接查询员工与其上级领导的关系。

介绍:

1.内连接:两张表没有主次关系;外连接:两张表产生了主次关系

2.带有right的是右外连接,又叫右连接;带有left的是左外连接,又叫左连接

3.任何一个左连接都有右连接的写法,任何一个右连接都有左连接的写法

4.right:表示将join关键字右边的这张表看成主表,主要是将该表的数据全部查询出来,捎带的查询左边的表

使用语法:

使用语法:

 select

        …

 from

        …

          表1 right(left) outer(可省略)

 join  表2

 on

        连接条件

查询员工的上级领导,要求显示员工名和对应的领导名,并且dept表全部显示

先查询两张表的信息

 

 右连接

 左连接

 注意:外连接的查询结果条数一定是大于内连接的查询结果条数

查询每个员工的上级领导,要求显示所有员工的名字和领导名

 

<think> 我们被要求回答关于外连接外连接的概念、用法及区别,并参考了用户提供的引用内容。根据引用,我们可以总结如下: 1. **概念**: - **外连接(LEFT OUTER JOIN)**:以表为基表,返回表的所有行,以及表中匹配的行。如果表没有匹配的行,则表的部分返回NULL。 - **外连接(RIGHT OUTER JOIN)**:以表为基表,返回表的所有行,以及表中匹配的行。如果表没有匹配的行,则表的部分返回NULL。 2. **用法**: - 外连接的语法:`SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.列 = 表2.列` - 外连接的语法:`SELECT 列名 FROM 表1 RIGHT JOIN 表2 ON 表1.列 = 表2.列` 3. **区别**: - 外连接关注表的所有数据,外连接关注表的所有数据。 - 在MySQL中,不支持全外连接(FULL OUTER JOIN),但可以通过外连接外连接的并集(UNION)来实现。 另外,引用中给出了示例数据以及查询结果,可以帮助理解。 根据引用[3]中的示例: - 外连接表(A表)的所有记录都会出现,表(B表)如果没有匹配,则用NULL填充。 - 外连接表(B表)的所有记录都会出现,表(A表)如果没有匹配,则用NULL填充。 同时,引用[4]提到,外连接中,表的一条记录如果在表没有匹配,则表部分为NULL;同样,外连接中,表的一条记录如果在表没有匹配,则表部分为NULL。 因此,我们可以这样组织回答: ### 外连接外连接详解 #### 1. 概念 - **外连接(LEFT OUTER JOIN)**:以表为基准,返回表的所有记录以及表中满足连接条件的记录。若表无匹配记录,则表字段以 NULL 填充。 - **外连接(RIGHT OUTER JOIN)**:以表为基准,返回表的所有记录以及表中满足连接条件的记录。若表无匹配记录,则表字段以 NULL 填充。 #### 2. 使用场景 - 当需要保留表全部数据并关联表数据时(即使表无对应数据),使用外连接。例如:查询所有员工及其部门信息(包括未分配部门的员工)。 - 当需要保留表全部数据并关联表数据时(即使表无对应数据),使用外连接。例如:查询所有部门及其员工信息(包括无员工的部门)。 #### 3. 语法格式(MySQL) ```sql -- 外连接 SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.关联列 = 表2.关联列; -- 外连接 SELECT 列名 FROM 表1 RIGHT JOIN 表2 ON 表1.关联列 = 表2.关联列; ``` #### 4. 示例分析 假设有以下两个表: - **员工表 (emp)** | id | name | dept_id | |----|------|---------| | 1 | 张三 | 101 | | 2 | 李四 | 102 | | 3 | 王五 | NULL | -- 未分配部门 - **部门表 (dept)** | id | dept_name | |----|-----------| |101 | 技术部 | |102 | 销售部 | |103 | 市场部 | -- 无员工 **外连接查询**(保留所有员工信息): ```sql SELECT emp.name, dept.dept_name FROM emp LEFT JOIN dept ON emp.dept_id = dept.id; ``` 结果: | name | dept_name | |------|-----------| | 张三 | 技术部 | | 李四 | 销售部 | | 王五 | NULL | -- 未分配部门的员工保留,部门信息为NULL **外连接查询**(保留所有部门信息): ```sql SELECT emp.name, dept.dept_name FROM emp RIGHT JOIN dept ON emp.dept_id = dept.id; ``` 结果: | name | dept_name | |------|-----------| | 张三 | 技术部 | | 李四 | 销售部 | | NULL | 市场部 | -- 无员工的部门保留,员工信息为NULL #### 5. 外连接外连接的转换 通过交换表位置,外连接可转换为外连接(反之亦然): ```sql -- 以下两句等价: SELECT * FROM 表A LEFT JOIN 表B ON A.id = B.id; SELECT * FROM 表B RIGHT JOIN 表A ON A.id = B.id; ``` #### 6. 全外连接的模拟实现 MySQL 不支持 `FULL OUTER JOIN`,但可通过 `UNION` 合并外连接外连接实现: ```sql SELECT * FROM emp LEFT JOIN dept ON emp.dept_id = dept.id UNION SELECT * FROM emp RIGHT JOIN dept ON emp.dept_id = dept.id; ``` 结果将包含所有员工所有部门,无匹配项的位置用 NULL 填充。 #### 7. 注意事项 - 外连接可能导致结果集变大(尤其当一侧表数据量大时)。 - 使用 `WHERE` 条件过滤时需谨慎: ```sql -- 错误:这将使外连接退化为内连接 SELECT * FROM emp LEFT JOIN dept ON emp.dept_id = dept.id WHERE dept.dept_name = '技术部'; -- 排除了NULL行 -- 正确:过滤条件应放在ON子句中 SELECT * FROM emp LEFT JOIN dept ON emp.dept_id = dept.id AND dept.dept_name = '技术部'; -- 保留所有员工,仅技术部有匹配 ``` > **总结**:外连接外连接的本质差异在于保留哪张表的完整数据。实际开发中,外连接使用频率更高,但需根据业务需求选择。 §§相关问题§§ 1. 如何在 MySQL 中实现全外连接(FULL OUTER JOIN)? 2. 外连接查询结果中 NULL 值如何处理? 3. 内连接(INNER JOIN)外连接的主要区别是什么? 4. 多表外连接查询有哪些注意事项? </think>### 外连接外连接详解 #### 一、核心概念 1. **外连接(LEFT OUTER JOIN)** - **保留表所有数据**:无论连接条件是否匹配,表的所有行都会出现在结果中 - **表数据匹配规则**: - 匹配成功:显示表对应数据 - 匹配失败:表字段显示 `NULL` ```sql SELECT * FROM 表 LEFT JOIN 表 ON 连接条件; ``` 2. **外连接(RIGHT OUTER JOIN)** - **保留表所有数据**:无论连接条件是否匹配,表的所有行都会出现在结果中 - **表数据匹配规则**: - 匹配成功:显示表对应数据 - 匹配失败:表字段显示 `NULL` ```sql SELECT * FROM 表 RIGHT JOIN 表 ON 连接条件; ``` #### 二、实际用法对比 ##### 示例数据 **员工表 (emp)** | id | name | dept_id | |----|-------|---------| | 1 | 张三 | 101 | | 2 | 李四 | 102 | | 3 | 王五 | NULL | ← 未分配部门 **部门表 (dept)** | id | dept_name | |-----|-----------| | 101 | 技术部 | | 102 | 销售部 | | 103 | 市场部 | ← 无员工 ##### 1. 外连接结果 ```sql SELECT emp.name, dept.dept_name FROM emp LEFT JOIN dept ON emp.dept_id = dept.id; ``` **结果**: | name | dept_name | |------|-----------| | 张三 | 技术部 | | 李四 | 销售部 | | 王五 | NULL | ← 保留未分配部门的员工 ##### 2. 外连接结果 ```sql SELECT emp.name, dept.dept_name FROM emp RIGHT JOIN dept ON emp.dept_id = dept.id; ``` **结果**: | name | dept_name | |------|-----------| | 张三 | 技术部 | | 李四 | 销售部 | | NULL | 市场部 | ← 保留无员工的部门 #### 三、核心区别总结 | 特性 | 外连接 | 外连接 | |--------------|-------------------------------|-------------------------------| | **基准表** | 表(`FROM`后的表) | 表(`JOIN`后的表) | | **保留数据** | 表所有记录 | 表所有记录 | | **NULL出现** | 表未匹配时显示NULL | 表未匹配时显示NULL | | **使用频率** | 较高(更符合逻辑顺序) | 较低(可通过交换表转为左连接)| | **本质关系** | `A LEFT JOIN B` ≡ `B RIGHT JOIN A` | #### 四、典型应用场景 1. **外连接适用场景** - 查询所有员工信息(包括未分配部门的员工) - 统计每个用户的订单量(包括未下单用户) 2. **外连接适用场景** - 查询所有部门信息(包括无员工的部门) - 统计所有产品的购买记录(包括未被购买的产品) #### 五、特殊技巧:全外连接模拟 MySQL不支持全外连接(FULL OUTER JOIN),但可通过组合实现: ```sql (SELECT * FROM emp LEFT JOIN dept ON emp.dept_id=dept.id) UNION (SELECT * FROM emp RIGHT JOIN dept ON emp.dept_id=dept.id); ``` **结果**: | name | dept_name | |------|-----------| | 张三 | 技术部 | | 李四 | 销售部 | | 王五 | NULL | | NULL | 市场部 | #### 六、注意事项 1. **过滤条件位置** ```sql -- 错误:WHERE会使外连接退化为内连接 SELECT * FROM emp LEFT JOIN dept ON emp.dept_id=dept.id WHERE dept.dept_name='技术部'; -- 会过滤掉王五 -- 正确:条件应放在ON子句 SELECT * FROM emp LEFT JOIN dept ON emp.dept_id=dept.id AND dept.dept_name='技术部'; -- 保留王五记录 ``` 2. **性能优化** - 对连接字段建立索引 - 避免在大型表上直接使用`SELECT *` - 优先使用内连接(当不需要保留未匹配数据时) > **关键结论**:/外连接的本质差异在于保留哪张表的完整数据。实际开发中,80%的场景使用外连接即可满足需求[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&jhan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值