MySQL内外连接实战详解

 更新时间:2025年08月07日 09:22:42   作者:茉莉玫瑰花茶  
文章详解MySQL内连接与外连接,内连接通过WHERE筛选匹配记录,外连接包括左、右连接,保留一侧全数据,包含案例与练习及LeetCode实战题目,对mysql内外连接实战案例相关知识感兴趣的朋友一起看看吧

表的连接分类

表的连接主要分为内连接和外连接两种类型。

内连接

内连接实际上就是利用WHERE子句对两种表形成的笛卡尔积进行筛选,这是我们前面学习的主要查询方式,也是开发过程中使用最多的连接查询。

我们除了可以使用“ , ”来隔离表,我们还可以使用下面的语法:和我们之前笛卡尔积,后面使用where条件筛选是一样的效果的!只不过下面的写法是比较标准的!

SELECT 字段 FROM 表1 INNER JOIN 表2 ON 连接条件 AND 其他条件;

前面学习的大部分查询都属于内连接。

案例:显示SMITH的名字和部门名称

传统写法:

SELECT ename, dname FROM EMP, DEPT WHERE EMP.deptno=DEPT.deptno AND ename='SMITH';
mysql> select emp.ename, dept.dname from emp, dept where emp.deptno=dept.deptno and emp.ename='SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+
1 row in set (0.00 sec)

标准内连接写法:

SELECT ename, dname FROM EMP INNER JOIN DEPT ON EMP.deptno=DEPT.deptno AND ename='SMITH';
mysql> select emp.ename, dept.dname from emp inner join dept on emp.deptno=dept.deptno and emp.ename='SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+
1 row in set (0.00 sec)

外连接

外连接分为左外连接和右外连接。

为主的在哪一边,基本就是使用那一边的连接方式!--- 后面的练习部分体现!!!

左外连接

如果联合查询时,左侧的表完全显示(左侧的信息不要做任何的过滤和筛选,完全保留)(即使右侧没有匹配记录),我们就称为左外连接

仅仅将 inner join 改成了 left join

SELECT 字段名 FROM 表名1 LEFT JOIN 表名2 ON 连接条件

创建测试表:

CREATE TABLE stu (id INT, name VARCHAR(30)); -- 学生表
INSERT INTO stu VALUES(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
CREATE TABLE exam (id INT, grade INT); -- 成绩表
INSERT INTO exam VALUES(1, 56),(2,76),(11, 8);
mysql> select * from stu;
+------+------+
| id   | name |
+------+------+
|    1 | jack |
|    2 | tom  |
|    3 | kity |
|    4 | nono |
+------+------+
4 rows in set (0.00 sec)
mysql> select * from exam;
+------+-------+
| id   | grade |
+------+-------+
|    1 |    56 |
|    2 |    76 |
|   11 |     8 |
+------+-------+
3 rows in set (0.00 sec)

查询所有学生的成绩,如果学生没有成绩也要显示个人信息:

SELECT * FROM stu LEFT JOIN exam ON stu.id=exam.id;
mysql> select * from stu left join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
|    3 | kity | NULL |  NULL |
|    4 | nono | NULL |  NULL |
+------+------+------+-------+
4 rows in set (0.00 sec)

这个查询会显示左边表的所有记录,即使右边表没有匹配的记录。

右外连接

如果联合查询时,右侧的表完全显示(即使左侧没有匹配记录),我们就称为右外连接。

SELECT 字段 FROM 表名1 RIGHT JOIN 表名2 ON 连接条件;

对stu表和exam表联合查询,显示所有成绩,即使没有对应学生:

SELECT * FROM stu RIGHT JOIN exam ON stu.id=exam.id;
mysql> select * from stu right join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
| NULL | NULL |   11 |     8 |
+------+------+------+-------+
3 rows in set (0.00 sec)

练习:

列出部门名称和这些部门的员工信息,同时列出没有员工的部门

方法一(使用左连接):

SELECT d.dname, e.* FROM dept d LEFT JOIN emp e ON d.deptno=e.deptno;
mysql> select d.dname, e.* from dept d left join emp e on d.deptno=e.deptno;
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| dname      | empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| ACCOUNTING | 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
| ACCOUNTING | 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| ACCOUNTING | 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| RESEARCH   | 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| RESEARCH   | 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| RESEARCH   | 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| RESEARCH   | 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| RESEARCH   | 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| SALES      | 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| SALES      | 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| SALES      | 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| SALES      | 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| SALES      | 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| SALES      | 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| OPERATIONS |   NULL | NULL   | NULL      | NULL | NULL                |    NULL |    NULL |   NULL |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
15 rows in set (0.00 sec)

方法二(使用右连接):

SELECT d.dname, e.* FROM emp e RIGHT JOIN dept d ON d.deptno=e.deptno;
mysql> select d.dname, e.* from emp e right join dept d on d.deptno=e.deptno;
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| dname      | empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| ACCOUNTING | 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
| ACCOUNTING | 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| ACCOUNTING | 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| RESEARCH   | 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| RESEARCH   | 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| RESEARCH   | 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| RESEARCH   | 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| RESEARCH   | 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| SALES      | 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| SALES      | 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| SALES      | 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| SALES      | 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| SALES      | 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| SALES      | 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| OPERATIONS |   NULL | NULL   | NULL      | NULL | NULL                |    NULL |    NULL |   NULL |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
15 rows in set (0.00 sec)

实战OJ题目

到此这篇关于MySQL内外连接详解的文章就介绍到这了,更多相关mysql内外连接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • win2003服务器下配置 MySQL 群集(Cluster)的方法

    win2003服务器下配置 MySQL 群集(Cluster)的方法

    MySQL 群集是 MySQL 适合于分布式计算环境的高可用、高冗余版本。它采用了 NDB Cluster 存储引擎,允许在 1 个群集中运行多个 MySQL 服务器。
    2010-12-12
  • Pentaho Kettle工具实现SQL Server到MySQL数据库的定时数据同步方案

    Pentaho Kettle工具实现SQL Server到MySQL数据库的定时数据同步方案

    本文介绍了使用Kettle工具实现SQL Server到MySQL数据库的定时数据同步方案,首先需放置数据库驱动并创建目标表结构,通过图形化界面配置转换流程,该方案无需编写代码,完全通过图形化操作即可实现跨数据库的定时数据同步
    2026-03-03
  • Mysql索引的类型和优缺点详解

    Mysql索引的类型和优缺点详解

    这篇文章主要为大家详细介绍了Mysql索引的类型和优缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 详解MySQL主从复制实战 - 基于GTID的复制

    详解MySQL主从复制实战 - 基于GTID的复制

    本篇文章主要介绍了MySQL主从复制实战 - 基于GTID的复制,基于GTID的复制是MySQL 5.6后新增的复制方式.有兴趣的可以了解一下。
    2017-03-03
  • Docker部署MySQL8.0从拉取镜像到配置远程访问完整指南

    Docker部署MySQL8.0从拉取镜像到配置远程访问完整指南

    在开发测试环境中,通过Docker部署MySQL 8.0可实现快速启动、环境隔离和数据持久化,这篇文章主要介绍了Docker部署MySQL8.0从拉取镜像到配置远程访问的相关资料,需要的朋友可以参考下
    2026-05-05
  • MySQL中跨表排序和指定类型置顶的四种写法详解

    MySQL中跨表排序和指定类型置顶的四种写法详解

    这篇文章主要介绍了MySQL跨表排序和固定置顶的两种排序需求的实现方法,并结合实战场景分析了四种解决方案,通过具体SQL示例和适用场景分析,帮助开发者更好地理解和应用这些排序策略
    2026-06-06
  • MySQL视图中用变量实现自动加入序号功能

    MySQL视图中用变量实现自动加入序号功能

    在 MySQL 中,视图不支持直接使用变量来生成序号,因为视图是基于静态 SQL 查询定义的,而变量是在运行时动态计算的,不过,你可以通过一些技巧来实现类似的效果,以下是一个常见的方法,使用子查询来初始化变量,然后在视图中使用这些变量,需要的朋友可以参考下
    2024-10-10
  • 解析MySQL binlog

    解析MySQL binlog

    我们都知道,binlog可以说是MySQL中比较重要的日志了,在日常学习及运维过程中,也经常会遇到。不清楚你对binlog了解多少呢?本篇文章将从binlog作用、binlog相关参数、解析binlog内容三个方面带你了解binlog
    2021-06-06
  • 远程访问MySQL数据库的方法小结

    远程访问MySQL数据库的方法小结

    MySQL数据库不允许从远程访问如何办?本文提供了 3种解决思路方法
    2009-12-12
  • mysql中索引使用不当速度比没加索引还慢的测试

    mysql中索引使用不当速度比没加索引还慢的测试

    mysql的索引使用不当速度比没加索引还慢,我们举个例子来解释一下。
    2011-08-08

最新评论