内联结,外联结,全连接,交叉连接的区别

本文详细介绍了SQL中的四种主要连接类型:内连接、左外连接、右外连接和交叉连接,并通过实例展示了这些连接如何工作。此外,还解释了自身连接的概念及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连接分为:内连接、外连接、交叉连接 
一、内连接——最常用 
定义:
仅将两个表中满足连接条件的行组合起来作为结果集。 
在内连接中,只有在两个表中匹配的行才能在结果集中出现 
关键词:INNER JOIN 
格式:SELECT 列名表 FROM 表名1 [INNER] JOIN 表名2 ON或WHERE 条件表达式 
说明: 
(1)列名表中的列名可以出自后面的两个表,但如果两个表中有同名列,应在列名前标明出处,格式为:表名.列名 
(2)若连接的两个表名字太长,可以为它们起个别名。 格式为:表名 AS 别名 
(3)INNER是默认方式,可以省略
eg:
select *
from   t_institution i
inner join t_teller t
on i.inst_no = t.inst_no
where i.inst_no = "5801"
其中inner可以省略。
等价于早期的连接语法
select *
from t_institution i, t_teller t
where i.inst_no = t.inst_no
and i.inst_no = "5801"

二、外连接 
1、左(外)连接 
定义:在内连接的基础上,还包含左表中所有不符合条件的数据行,并在其中的右表列填写NULL 
关键字:LEFT JOIN
eg:
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
其中outer可以省略。
注意: 
当在内连接查询中加入条件是,无论是将它加入到join子句,还是加入到where子句,其效果是完全一样的,但对于外连接情况就不同了。当把条件加入到 join子句时,SQL Server、Informix会返回外连接表的全部行,然后使用指定的条件返回第二个表的行。如果将条件放到where子句 中,SQL Server将会首先进行连接操作,然后使用where子句对连接后的行进行筛选。下面的两个查询展示了条件放置位子对执行结果的影响:
条件在join子句
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
and i.inst_no = “5801”

结果是:
inst_no     inst_name             inst_no     teller_no   teller_name
5801        天河区                5801        0001        tom
5801        天河区                5801        0002        david
5802        越秀区
5803        白云区

条件在where子句
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
where i.inst_no = “5801”

结果是:
inst_no     inst_name             inst_no     teller_no   teller_name
5801           天河区                    5801          0001               tom
5801           天河区                    5801          0002              david

2、右(外)连接 
定义:
在内连接的基础上,还包含右表中所有不符合条件的数据行,并在其中的左表列填写NULL 
关键字:RIGHT JOIN 
3、完全连接 
定义:
在内连接的基础上,还包含两个表中所有不符合条件的数据行,并在其中的左表、和右表列填写NULL 
关键字:FULL JOIN

三、交叉连接 
定义:
将两个表的所有行进行组合,连接后的行数为两个表的乘积数。(笛卡尔积) 
关键词:CROSS JOIN 
格式:FROM 表名1 CROSS JOIN 表名2

四, 自身连接
自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如人力资源数据库中雇员与老板的关系。
下面例子是在机构表中查找本机构和上级机构的信息。
select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name
from t_institution i
join t_institution s
on i.superior_inst = s.inst_no

结果是:
superior_inst sup_inst_name         inst_no     inst_name
800                             广州市                5801        天河区
800                             广州市                5802        越秀区
800                             广州市                5803        白云区

内联接显示的是两列数据匹配下的相关数据,外联接分为左外联接右外联接和全联接,mysql中不支持全联接,所以以左外联接为例来讨论区别,左外联接是只在join前面是这张表不管是否两张有无满足的匹配信息,这张表的内容都要全部显示,而后面的那张表只显示匹配的信息。右外联接则刚好相反。

转载自:脚本之家

### SQL 自然连接无公共属性的替代方案 当两张表之间不存在任何共同的列名时,执行自然连接(`NATURAL JOIN`)会导致结果为空集,因为自然连接依赖于两个表之间的同名列来匹配记录。如果两表没有任何公共属性,则无法通过 `NATURAL JOIN` 实现有效的关联。 在这种情况下,可以通过其他类型的连接操作实现表间的关联,具体方法如下: #### 使用显式的 `ON` 子句定义条件 即使两表间没有共享的列名称,也可以通过指定明确的联结条件来进行连接。例如,假设存在两张表 `r1` 和 `r2`,它们分别有唯一的主键列 `id_r1` 和 `id_r2`,以及某些业务逻辑表明这两张表应该基于某种映射关系进行连接。此时可以使用普通的 `INNER JOIN` 或者其他形式的连接,并提供具体的联结条件[^2]。 ```sql SELECT r1.*, r2.* FROM r1 INNER JOIN r2 ON r1.some_column = r2.other_column; ``` 上述例子展示了如何利用特定的列作为桥梁完成跨表的数据检索工作。需要注意的是这里的 `some_column` 和 `other_column` 并不需要具有相同的名称;只要能够表达两者之间的对应关系即可。 #### 如果完全缺乏可比较字段则考虑交叉乘积(CROSS JOIN) 如果没有找到合适的字段用于建立联系,那么可能需要采用笛卡尔积的方式——即让每条来自第一个表中的记录都与第二个表里的所有行配对一次形成新的组合集合。这通常不是理想的解决方案,因为它会产生大量的冗余数据项,但在特殊场景下也许正是所期望的结果[^1]。 ```sql SELECT * FROM r1, r2 -- 等价写法: FROM r1 CROSS JOIN r2 WHERE ... ; /* 可选过滤器 */ ``` 注意,在实际应用之前应当仔细评估是否真的有必要生成如此庞大的输出规模,并且要记得加入必要的筛选标准减少不必要的计算量。 #### 键设计优化建议 为了便于后续维护和理解数据库结构,推荐遵循一定的命名约定给键加上前缀比如 'fk_' ,从而一眼就能辨认出某个字段代表部参照关系[^3] 。良好的物理模型有助于提高查询效率并降低错误风险。 --- ### 总结 对于不含有相同属性的表格实施自然连结是不可能达成目标的,应转而寻求诸如内连结(INNER JOIN),左/右连结(LEFT/RIGHT OUTER JOIN)或者全连结(FULL OUTER JOIN)等形式之一配合自定约束语句来满足需求。另,在规划初期就充分考虑到实体间相互作用并通过合理设置键等方式预先设定好潜在路径也是十分重要的策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值