SQL联结
1联结
🤔 那我们又该如何创建联结呢?
So easy!
👉 规定要联结的所有表以及它们如何关联就可以了。
在设置关联条件时,为避免不同表被引用的列名相同,我们需要使用完全限定列名(用一个点分隔表名和列名),否则会返回错误。
用法如下:
table1
.common_field
= table2
.common_field
教师表的主键 id 为设置的关联条件为:
teachers
.id
= courses
.teacher_id
1.1JOIN连接子句
SQL JOIN 连接子句用于将数据库中两个或者两个以上表中的记录组合起来。
其类型主要分为 INNER JOIN(内连接)、OUTER JOIN(外连接)、全连接(FULL JOIN)和交叉连接(CROSS JOIN),其中 OUTER JOIN 又可以细分为 LEFT JOIN(左连接)和 RIGHT JOIN(右连接)。
因此,我们主要使用的 JOIN 连接类型如下:
- INNER JOIN:如果表中有至少一个匹配,则返回行
- LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
- RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
- FULL JOIN:只要其中一个表中存在匹配,则返回行
- CROSS JOIN:又称笛卡尔积,两个表数据一一对应,返回结果的行数等于两个表行数的乘积
2内连接INNER JOIN
最常用也最重要的多表联结类型就是 INNER JOIN(内连接),有时候也被称作 EQUIJOIN(等值连接)。
内连接根据联结条件来组合两个表中的字段,以创建一个新的结果表。
假如我们想将表 1 和表 2 进行内连接,SQL 查询会逐个比较表 1 和表 2 中的每一条记录,来寻找满足联结条件的所有记录对。当联结条件得以满足时,所有满足条件的记录对的字段将会结合在一起构成结果表。
简单的说,内连接就是取两个表的交集,返回的结果就是连接的两张表中都满足条件的部分。
2.1内连接基本语法
基本语法有如下两种写法:
SELECT `table1`.`column1`, `table2`.`column2`... FROM `table1` INNER JOIN `table2` ON `table1`.`common_field` = `table2`.`common_field`;
或
SELECT `table1`.`column1`, `table2`.`column2`... FROM `table1` JOIN `table2` ON `table1`.`common_field` = `table2`.`common_field`;
注:INNER JOIN 中 INNER 可以省略不写
详细语法如下所示:
FROM table1 INNER JOIN table2 ON table1.common_field = table2.common_field
table1 和 table2 是内连接的两个表名,table1.common_field 和 table2.common_field
需要注意的是,联结条件需使用特定的 ON 子句给出。
表定义 1 :courses (课程表)
列名 类型 注释
id int unsigned 主键
name varchar 课程名称
student_count int 学生总数
created_at date 创建课程时间
teacher_id int 讲师 id
表定义 2 : teachers (教师表)
列名 类型 注释
id int 主键
name varchar 讲师姓名
email varchar 讲师邮箱
age int 讲师年龄
country varchar 讲师国籍
假如现在正处于新学期选课的阶段,我们想要查询一下新学期有哪些开设的课程可以选择,还想要获得开设这些课程教师的邮箱以便联系,我们该编写怎么样的 SQL 语句呢?
我们可以使用下面的 SQL 语句:
SELECT `c`.`id`, `c`.`name` AS `course_name`, `t`.`email` AS `teacher_email` FROM `courses` `c` INNER JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id`;
3外连接OUTER JOIN
外连接在生活中是经常用到的,外连接也是针对于两张表格之间,比如我们实际应用过程会发现,会有一些新任职的教师,还在实习期,并无对应课程安排,那若是按照上一节使用内连接的话,这些教师的课程信息将无法导出来,我们应该如何操作呢?
这个就要用到我们的外连接,外连接可以将某个表格中,在另外一张表格中无对应关系,但是也能将数据匹配出来。
在MySQL中,外连接查询会返回所操作的表中至少一个表的所有数据记录。在MySQL中,数据查询通过SQL语句 “OUTER JOIN…ON” 来实现,外连接查询可以分为以下三类:
- 左外连接
- 右外连接
- 全外连接
外连接数据查询语法如下:
SELECT column_name 1,column_name 2 ... column_name n FROM table1 LEFT | RIGHT | FULL (OUTER) JOIN table2 ON CONDITION;
3.1左外连接LEFT JOIN
外连接查询中的左外连接就是指新关系中执行匹配条件时,以关键字 LEFT JOIN 左边的表为参考表。
左外连接的结果包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是连接列所匹配的行,这就意味着,左连接会返回左表中的所有记录,加上右表中匹配到的记录。如果左表的某行在右表中没有匹配行,那么在相关联的结果行中,右表的所有选择列表均为空值。
语法:
SELECT column_name 1,column_name 2 ... column_name n FROM table1 LEFT JOIN table2 ON CONDITION ;
现在学校想要统计所有的在校教师姓名及其所教课程的名称,希望能得到你的帮助。
在这里我们要查询的信息是在俩个表当中的,我们要先把表关联到一起(“teachers” 作为左表,“courses“ 作为右表)然后在进行查找。
使用 SQL 中子查询的方式如下:
SELECT c.name AS course_name, t.name AS teacher_name FROM teachers t LEFT JOIN courses c ON c.teacher_id = t.id;
3.2右外连接RIGHT JOIN
外连接查询中的右外连接是指新关系中执行匹配条件时,以关键字 RIGHT JOIN 右边的表为参考表,如果右表的某行在左表中没有匹配行,左表就返回空值。
SELECT column_name 1,column_name 2 ... column_name n FROM table1 RIGHT JOIN table2 ON CONDITION ;
👇 我们可以通过下面的实例来感受一下 RIGHT JOIN 的用法。
现在学校想要统计所有的在校教师姓名、教师邮箱及其所教课程的名称,希望能得到你的帮助。
在这里我们将 “teachers” 作为右表,“courses“ 作为左表然后在进行查找。
使用 SQL 中子查询的方式如下:
SELECT c.name AS course_name, t.name AS teacher_name,t.email AS teacher_email FROM courses c RIGHT JOIN teachers t ON c.teacher_id = t.id;
3.3全外连接FULL(OUTER) JOIN
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行
FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。
注:MySQL 数据库不支持全连接,想要实现全连接可以使用 UNION ALL 来将左连接和右连接结果组合在一起实现全连接。
UNION :联合的意思,即把两次或多次查询结果合并起来
要求:两次查询的列数必须一致,同时,每条 SELECT 语句中的列的顺序必须相同
推荐:列的类型可以不一样,但推荐查询的每一列,相对于的类型应该一样
可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准,即UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么 UNION 会将相同的行合并,最终只保留一行。也可以这样理解,UNION 会去掉重复的行。
如果不想去掉重复的行,可以使用 UNION ALL 。
如果子句中有 order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。
先左连接,后右连接
SELECT column_name 1,column_name 2 ... column_name n FROM table1 LEFT JOIN table2 ON CONDITION UNION SELECT column_name 1,column_name 2 ... column_name n FROM table1 RIGHT JOIN table2 ON CONDITION ;
eg:
SELECT `c`.`name` AS `course_name`, `t`.`age` AS `teacher_age` FROM `courses` `c` LEFT JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id` UNION SELECT `c`.`name` AS `course_name`, `t`.`age` AS `teacher_age` FROM `courses` `c` RIGHT JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id`;
posted on 2023-03-12 15:59 JavaCoderPan 阅读(60) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南