当前位置: 首页 > news >正文

MySQL表的内连和外连

目录

  • 表的内连和外连
    • 内连接
    • 外连接
      • 左外连接
      • 右外连接

表的内连和外连

表的连接分为内连接和外连接

内连接

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

通俗解释:内连接就像一次“严格匹配”的相亲大会。只把双方都符合条件(有共同department_id) 的信息配对成功并展示出来如果有人没有对象(比如赵六的department_id是NULL),或者有对象但对方没来(比如市场部在员工表里没人),那他们就不会出现在结果里

语法:

select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;

inner join 可以简写成 join,因为MySQL默认就是内连接。

备注:前面学习的都是内连接

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

-- 用前面的写法
mysql> select ename,dname from emp,dept where emp.deptno = dept.deptno and ename = 'SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+
1 row in set (0.00 sec)-- 用标准的内连接写法
mysql> select ename,dname from emp inner join dept on emp.deptno=dept.deptno and ename='SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+
1 row in set (0.00 sec)

使用场景:当你只想获取在两个表中都有对应关系的数据时,就用内连接。

  • 查询订单和客户信息(只查看已下单的客户)。
  • 查询学生和选课信息(只查看有学生选的课程)。
  • 查询文章和评论(只查看有评论的文章)。

外连接

外连接分为左外连接、右外连接和全外连接。MySQL不支持全外连接,所以我们重点讲前两个。

左外连接

如果联合查询,左侧的表完全显示我们就说是左外连接。

左外连接 - “以左表为绝对核心”
通俗解释:左连接就像公司的人力资源部做全员统计。左边的员工表是核心,一个都不能少。不管员工有没有部门(department_id是否为空),都要出现在名单上。然后,再去右边的部门表里找匹配的部门名称,如果找不到,就用NULL填充。

语法:

select 字段名 from 表名1 left join 表名2 on 连接条件

案例:

--- 创建两张表
mysql> create table stu( id int, name varchar(30));
Query OK, 0 rows affected (0.02 sec)mysql> create table exam(-> id int,-> grade int);
Query OK, 0 rows affected (0.02 sec)mysql> insert into stu values (1,'Jon'),(2,'Tom'),(4,'Lisa'),(5,'Lili');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0mysql> insert into exam values(1,12),(2,34),(11,9);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0mysql> select * from stu;
+------+------+
| id   | name |
+------+------+
|    1 | Jon  |
|    2 | Tom  |
|    4 | Lisa |
|    5 | Lili |
+------+------+
4 rows in set (0.00 sec)mysql> select * from exam;
+------+-------+
| id   | grade |
+------+-------+
|    1 |    12 |
|    2 |    34 |
|   11 |     9 |
+------+-------+
3 rows in set (0.00 sec)
  • 查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
-- 左外连接:当左边表和右边表没有匹配时,也会显示左边表的数据
mysql> select * from stu left join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | Jon  |    1 |    12 |
|    2 | Tom  |    2 |    34 |
|    4 | Lisa | NULL |  NULL |
|    5 | Lili | NULL |  NULL |
+------+------+------+-------+
4 rows in set (0.00 sec)
--- 内连接:只显示匹配数据
mysql> select * from stu inner join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | Jon  |    1 |    12 |
|    2 | Tom  |    2 |    34 |
+------+------+------+-------+
2 rows in set (0.00 sec)

使用场景:当你需要获取左表的全部记录,以及右表中与之匹配的记录时。

  • 统计每个客户的订单量(包括没下过单的客户)。
  • 查找所有员工的信息,包括尚未分配部门的员工(如上例)。
  • 计算每个产品的销售总额,包括一件都没卖出去的产品。

右外连接

如果联合查询,右侧的表完全显示我们就说是右外连接。

右外连接 - “以右表为绝对核心”
通俗解释:右连接和左连接完全相反。它以右边的表为核心,一个都不能少。然后去左边的表里找匹配项,找不到就用NULL填充。在实际开发中,右连接用得较少,因为我们可以通过调整表的顺序,用左连接来实现同样的效果,这样代码更统一,更易读。

语法:

select 字段 from 表名1 right join 表名2 on 连接条件;

案例:

  • 对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
mysql> select * from stu right join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | Jon  |    1 |    12 |
|    2 | Tom  |    2 |    34 |
| NULL | NULL |   11 |     9 |
+------+------+------+-------+
3 rows in set (0.00 sec)

练习:

  • 列出部门名称和这些部门的员工信息,同时列出没有员工的部门
--- 方法1:使用左外连接
mysql> select dept.deptno,dept.dname,empno,ename,job from dept left join emp on dept.deptno=emp.deptno;
+--------+------------+--------+--------+-----------+
| deptno | dname      | empno  | ename  | job       |
+--------+------------+--------+--------+-----------+
|     10 | ACCOUNTING | 007934 | MILLER | CLERK     |
|     10 | ACCOUNTING | 007839 | KING   | PRESIDENT |
|     10 | ACCOUNTING | 007782 | CLARK  | MANAGER   |
|     20 | RESEARCH   | 007902 | FORD   | ANALYST   |
|     20 | RESEARCH   | 007876 | ADAMS  | CLERK     |
|     20 | RESEARCH   | 007788 | SCOTT  | ANALYST   |
|     20 | RESEARCH   | 007566 | JONES  | MANAGER   |
|     20 | RESEARCH   | 007369 | SMITH  | CLERK     |
|     30 | SALES      | 007900 | JAMES  | CLERK     |
|     30 | SALES      | 007844 | TURNER | SALESMAN  |
|     30 | SALES      | 007698 | BLAKE  | MANAGER   |
|     30 | SALES      | 007654 | MARTIN | SALESMAN  |
|     30 | SALES      | 007521 | WARD   | SALESMAN  |
|     30 | SALES      | 007499 | ALLEN  | SALESMAN  |
|     40 | OPERATIONS |   NULL | NULL   | NULL      |
+--------+------------+--------+--------+-----------+
15 rows in set (0.00 sec)

这个查询和上面的右连接查询结果完全一样。所以,掌握左连接就足够了。

--- 方法2:使用右外连接
mysql> select dept.deptno,dept.dname,empno,ename,job from emp right join dept on dept.deptno=emp.deptno;
+--------+------------+--------+--------+-----------+
| deptno | dname      | empno  | ename  | job       |
+--------+------------+--------+--------+-----------+
|     10 | ACCOUNTING | 007934 | MILLER | CLERK     |
|     10 | ACCOUNTING | 007839 | KING   | PRESIDENT |
|     10 | ACCOUNTING | 007782 | CLARK  | MANAGER   |
|     20 | RESEARCH   | 007902 | FORD   | ANALYST   |
|     20 | RESEARCH   | 007876 | ADAMS  | CLERK     |
|     20 | RESEARCH   | 007788 | SCOTT  | ANALYST   |
|     20 | RESEARCH   | 007566 | JONES  | MANAGER   |
|     20 | RESEARCH   | 007369 | SMITH  | CLERK     |
|     30 | SALES      | 007900 | JAMES  | CLERK     |
|     30 | SALES      | 007844 | TURNER | SALESMAN  |
|     30 | SALES      | 007698 | BLAKE  | MANAGER   |
|     30 | SALES      | 007654 | MARTIN | SALESMAN  |
|     30 | SALES      | 007521 | WARD   | SALESMAN  |
|     30 | SALES      | 007499 | ALLEN  | SALESMAN  |
|     40 | OPERATIONS |   NULL | NULL   | NULL      |
+--------+------------+--------+--------+-----------+
15 rows in set (0.00 sec)
--- 可以使用别名
mysql> select d.deptno,d.dname,e.empno,e.ename,e.job from emp e right join dept d on d.deptno=e.deptno;

在这里插入图片描述

一句话记忆:
内连接:求交集,严格匹配。
左连接:保左全,右填空。
右连接:保右全,左填空(但通常用“调换表顺序的左连接”来代替)。

http://www.dtcms.com/a/437967.html

相关文章:

  • go 基础
  • 鸿蒙开发3--UI布局(玩转鸿蒙的Row、Column与Stack容器)
  • 为什么要给企业建设网站做单位网站
  • ML4T - 第7章第8节 利用LR预测股票价格走势Predicting stock price moves with Logistic Regression
  • 性能之巅:大小水管问题深究
  • css选择器(继承补充)
  • 郑州高新区做网站的公司聚美优品的电子商务网站建设论文
  • uniapp集成语音识别与图片识别集成方案【百度智能云】
  • SpringCloud API Gateway2.0如何解决docker中应用间IP漂移的正确手法
  • 鸿蒙Next中使用mDNS发现局域网服务:完整指南与实战
  • 长泰建设局网站注册网站多久
  • 孝感网站开发江苏建设服务信息网站
  • 数据分析概述与环境搭建
  • 易语言网站怎么做帕绍网站建设
  • vue3父组件和子组件之间传递数据
  • Coze源码分析-资源库-编辑工作流-前端源码-核心流程/API/总结
  • Netty服务器监听读写超时
  • PHP 中的正则表达式
  • Linux的Socket编程之UDP
  • 环境没有tomcat怎么演示自己做的网站动漫设计专业就业方向
  • 180课时吃透Go语言游戏后端开发7:Go语言中的函数
  • Python核心架构深度解析:从解释器原理到GIL机制全面剖析
  • 数据结构_哈夫曼编码(Huffman)完整指南:从原理到实现,附考研真题详解
  • 怎样做网站吸引客户网站开发专业就业前系军
  • 四川建站模板网站公司有哪些做任务网站
  • 藏语自然语言处理入门 - 5 文本归类
  • Stanford CS336 assignment1 | Transformer Language Model Architecture
  • 告别人工出题!PromptCoT 2.0 让大模型自己造训练难题,7B 模型仅用合成数据碾压人工数据集效果!
  • Prompt Programming - 用文字重构AI智能体系
  • 基于提示学习的多模态情感分析系统:从MULT到PromptModel的华丽升级