内连接、左外连接、右外连接、全外连接、交叉连接(CROSS JOIN)-----小知识解决大数据攻略

本文详细介绍了SQL中的不同连接类型,包括内连接、左外连接、右外连接、全外连接和自连接等,并通过具体实例进行了说明。这些连接方式有助于在复杂的数据库查询中更灵活地获取所需数据。

 

       早就听说了内连接与外连接,以前视图中使用过、这次自考也学习了,只是简单理解,现在深入探究学习(由于上篇博客的出现)与实践:

概念

关键字: 左右连接 数据表的连接有:

1、内连接(自然连接): 只有两个表相匹配的行才能在结果集中出现

 

2、外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制)

 

3、自连接(连接发生在一张基表内)

 

实例

以下是自己通过小实例来深刻的理解,以免混淆

 我有两张简单的信息表来说明问题

test1:

 

test2:

 

交叉连接(CROSS JOIN)也叫做笛卡尔积

SELECT     dbo.test1.name, dbo.test1.sex, dbo.test2.name2, dbo.test2.age
FROM         dbo.test1 CROSS JOIN
                      dbo.test2


 

内连接

SELECT     dbo.test1.name, dbo.test1.sex, dbo.test2.name2, dbo.test2.age
FROM         dbo.test1  inner JOIN dbo.test2  on test1.name =test2.name2


 

左外连接

SELECT     dbo.test1.name, dbo.test1.sex, dbo.test2.name2, dbo.test2.age
FROM         dbo.test1  left JOIN dbo.test2  on test1.name =test2.name2


右外连接

SELECT     dbo.test1.name, dbo.test1.sex, dbo.test2.name2, dbo.test2.age
FROM         dbo.test1  right JOIN dbo.test2  on test1.name =test2.name2

 

全外连接

SELECT     dbo.test1.name, dbo.test1.sex, dbo.test2.name2, dbo.test2.age
FROM         dbo.test1  full outer JOIN dbo.test2  on test1.name =test2.name2



总结

 

       通过这几种数据的关系可以查找自己想要的数据不用太拘于主外键了(以前没有主外键就不会查找有关系的数据了),这些知识看似简单,但是在大型数据的分析与使用中,可以简化我们的数据逻辑,提高我们的查询效率。

 

<think>我们正在讨论SQL中的连接类型:内连接连接和连接。根据引用[1][2][3][4],我们可以总结如下: 1. **内连接(INNER JOIN)**: - 只返回两个表中连接条件匹配的记录。 - 如果表A和表B进行内连接,那么结果集中只包含A和B都满足连接条件的记录。 - 语法:`SELECT ... FROM tableA [INNER] JOIN tableB ON condition` 2. **连接(LEFT JOIN)**: - 返回表(tableA)的所有记录,以及表(tableB)中匹配的记录。 - 如果表中没有匹配的记录,则结果集中表的部分为NULL。 - 语法:`SELECT ... FROM tableA LEFT [OUTER] JOIN tableB ON condition` 3. **连接(RIGHT JOIN)**: - 返回表(tableB)的所有记录,以及表(tableA)中匹配的记录。 - 如果表中没有匹配的记录,则结果集中表的部分为NULL。 - 语法:`SELECT ... FROM tableA RIGHT [OUTER] JOIN tableB ON condition` 此外,引用[4]还给出了连接和连接的示例结果,直观地展示了连接的效果。 为了更清晰地展示区别,我们假设有两个表: **表A (Students)** | id | name | |----|------| | 1 | 张三 | | 2 | 李四 | | 3 | 王五 | **表B (Scores)** | student_id | score | |------------|-------| | 1 | 90 | | 3 | 85 | | 4 | 70 | ### 内连接(INNER JOIN)结果: ```sql SELECT A.id, A.name, B.score FROM Students A INNER JOIN Scores B ON A.id = B.student_id; ``` 结果(只返回A和B都有的记录): | id | name | score | |----|------|-------| | 1 | 张三 | 90 | | 3 | 王五 | 85 | ### 连接(LEFT JOIN)结果: ```sql SELECT A.id, A.name, B.score FROM Students A LEFT JOIN Scores B ON A.id = B.student_id; ``` 结果(包含A的所有记录,B没有匹配的则为NULL): | id | name | score | |----|------|-------| | 1 | 张三 | 90 | | 2 | 李四 | NULL | | 3 | 王五 | 85 | ### 连接(RIGHT JOIN)结果: ```sql SELECT A.id, A.name, B.score FROM Students A RIGHT JOIN Scores B ON A.id = B.student_id; ``` 结果(包含B的所有记录,A没有匹配的则为NULL): | id | name | score | |------|------|-------| | 1 | 张三 | 90 | | 3 | 王五 | 85 | | NULL | NULL | 70 | -- 注意:这里B表有一条记录(student_id=4)在A表中没有对应,所以A表字段为NULL ### 总结区别: | 连接类型 | 别名 | 结果集特点 | 常用场景 | |----------|----------------|----------------------------------------------|------------------------------------------------------| | 内连接 | INNER JOIN | 只返回匹配的行 | 需要两个表关联数据且只关心匹配项时 | | 连接 | LEFT JOIN | 表全部行 + 表匹配行(不匹配则NULL) | 主表数据必须保留,关联表信息可有可无(如用户订单统计) | | 连接 | RIGHT JOIN | 表全部行 + 表匹配行(不匹配则NULL) | 表为主表时(较少用,通常用连接替代)[^1] | > 注意:实际开发中,由于SQL语句从执行的习惯,连接使用频率高于连接。可通过调整表顺序用连接实现连接效果[^3]。 ### 进阶说明: - **全外连接(FULL OUTER JOIN)**:返回两表的全部记录,不匹配的部分用NULL填充(MySQL不支持,但可通过`LEFT JOIN + RIGHT JOIN + UNION`实现)[^3]。 - **交叉连接CROSS JOIN)**:返回两表的笛卡尔积(无连接条件)[^2]。 --- ### 相关问题 1. 如何用连接模拟实现连接的效果? 2. MySQL中如何实现全外连接(FULL OUTER JOIN)? 3. 在多表连接时,连接顺序对查询结果和性能有什么影响? 4. 等值连接(Equi-Join)和自然连接(Natural Join)分别是什么?它们与内连接有何异同? </think>### SQL连接类型详解:内连接连接与连接的区别 #### 1. **内连接(INNER JOIN)** - **核心特点**:仅返回两个表中**完全匹配**的记录 - **结果集**:$$A \cap B$$ - **类比**:取两表的交集 - **示例**: ```sql SELECT * FROM Employees e INNER JOIN Departments d ON e.dept_id = d.id; ``` - **结果说明**:只显示有部门的员工数据(无部门的员工和空部门都不会显示)[^1][^2] #### 2. **连接(LEFT JOIN)** - **核心特点**:返回**表所有记录** + **表匹配记录** - **结果集**:$$A \cup (A \cap B)$$ - **类比**:以表为主体的包含查询 - **示例**: ```sql SELECT * FROM Employees e LEFT JOIN Departments d ON e.dept_id = d.id; ``` - **结果说明**: - 有部门的员工:显示部门信息 - 无部门的员工:部门字段显示`NULL` - 无员工的部门:不显示[^1][^4] #### 3. **连接(RIGHT JOIN)** - **核心特点**:返回**表所有记录** + **表匹配记录** - **结果集**:$$B \cup (A \cap B)$$ - **类比**:以表为主体的包含查询 - **示例**: ```sql SELECT * FROM Employees e RIGHT JOIN Departments d ON e.dept_id = d.id; ``` - **结果说明**: - 有员工的部门:显示员工信息 - 无员工的部门:员工字段显示`NULL` - 无部门的员工:不显示[^1][^4] --- ### 区别对比表 | 特性 | 内连接 | 连接 | 连接 | |---------------------|---------------------------|-------------------------------|-------------------------------| | **结果集范围** | 仅匹配记录 | 表全部+表匹配 | 表全部+表匹配 | | **NULL值处理** | 不产生NULL | 表不匹配时产生NULL | 表不匹配时产生NULL | | **基础表** | 无主从关系 | 表为基础表 | 表为基础表 | | **语法关键字** | `INNER JOIN` 或 `JOIN` | `LEFT JOIN` 或 `LEFT OUTER JOIN` | `RIGHT JOIN` 或 `RIGHT OUTER JOIN` | | **使用频率** | ★★★★ | ★★★★★ | ★★ | > **关键差异图示**: > $$ > \begin{array}{c|c|c} > \text{内连接} & \text{连接} & \text{连接} \\ > \hline > \begin{tikzpicture}[scale=0.5] > \draw (0,0) circle (1) node {$A$}; > \draw (2,0) circle (1) node {$B$}; > \fill[red!30] (0.5,0) circle (0.8); > \end{tikzpicture} & > \begin{tikzpicture}[scale=0.5] > \draw (0,0) circle (1) node {$A$}; > \draw (2,0) circle (1) node {$B$}; > \fill[blue!30] (0,0) circle (1); > \fill[red!30] (0.5,0) circle (0.8); > \end{tikzpicture} & > \begin{tikzpicture}[scale=0.5] > \draw (0,0) circle (1) node {$A$}; > \draw (2,0) circle (1) node {$B$}; > \fill[blue!30] (2,0) circle (1); > \fill[red!30] (1.5,0) circle (0.8); > \end{tikzpicture} > \end{array} > $$ > *红色区域表示返回的数据范围* --- ### 实际应用场景 1. **内连接适用**:获取有完整关联信息的记录(如:订单和商品详情) 2. **连接适用**:保留主表所有数据的统计(如:所有员工及其部门,含未分配部门的员工) 3. **连接适用**:需要强制展示维度表的场景(如:所有部门及其员工,含未招聘的部门)[^3] > **注意**:MySQL等数据库没有`FULL OUTER JOIN`,可通过组合实现: > ```sql > SELECT * FROM A LEFT JOIN B ON ... > UNION > SELECT * FROM A RIGHT JOIN B ON ... > ``` --- ### 相关问题 1. 多表连接时不同类型的JOIN混合使用会产生什么效果? 2. 如何优化包含LEFT JOIN大数据量表查询性能? 3. 在哪些场景下应该避免使用RIGHT JOIN? 4. 等值连接(Equi-Join)和自然连接(Natural Join)与内连接有何异同?[^2][^3] 5. 如何通过执行计划分析不同连接类型的性能差异?
评论 23
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值