数据库系统概论(九)SQL连接查询语言超详细讲解(附带例题,表格详细讲解对比带你一步步掌握)

数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)

  • 前言
  • 一、关系代数中的连接运算是什么
    • [1. 一般连接(条件连接)](#1. 一般连接(条件连接))
    • [2. 等值连接](#2. 等值连接)
    • [3. 自然连接](#3. 自然连接)
    • [4. 外连接(保留未匹配的行)](#4. 外连接(保留未匹配的行))
      • [1. 左外连接](#1. 左外连接)
      • [2. 右外连接](#2. 右外连接)
      • [3. 全外连接](#3. 全外连接)
    • 总结
  • 二、连接查询是什么
    • [1. 什么是连接查询?](#1. 什么是连接查询?)
    • [2. 为什么需要连接查询?](#2. 为什么需要连接查询?)
    • [3. 连接查询的基本结构](#3. 连接查询的基本结构)
      • [1. FROM子句:告诉计算机要查哪些表](#1. FROM子句:告诉计算机要查哪些表)
      • [2. WHERE子句:告诉计算机如何"连接"表](#2. WHERE子句:告诉计算机如何“连接”表)
    • [4. 连接字段的要求](#4. 连接字段的要求)
    • [5. 总结](#5. 总结)
  • 三、连接查询
    • [1. 等值与非等值的连接查询](#1. 等值与非等值的连接查询)
    • [2. 自然连接查询](#2. 自然连接查询)
    • [3. 复合条件连接查询](#3. 复合条件连接查询)
    • [4. 自身连接查询](#4. 自身连接查询)
    • 5.外连接查询
      • [1. 外连接与普通连接的区别](#1. 外连接与普通连接的区别)
      • [2. 外连接的类型](#2. 外连接的类型)
      • [3. MySQL 外连接语法](#3. MySQL 外连接语法)
    • [6. 多表连接查询](#6. 多表连接查询)
      • [1. 什么是多表连接?](#1. 什么是多表连接?)
      • [2. 多表连接的两种写法](#2. 多表连接的两种写法)
      • [3. 多表连接示例](#3. 多表连接示例)
      • [4. 多表连接的注意事项](#4. 多表连接的注意事项)

前言

  • 之前我们已经简单认识了 SQL 语言(结构化查询语言),并了解了它的基本概念(比如表、元组、属性、数据库等)。
  • 现在,我们正式进入 SQL 核心功能 的学习 ------ SQL 查询语言,这是日常使用最频繁、也是掌握 SQL 的关键部分。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的数据库系统概论专栏
https://blog.csdn.net/2402_83322742/category_12911520.html?spm=1001.2014.3001.5482


一、关系代数中的连接运算是什么

  • 关系代数中的连接运算,简单来说就是把两个表格(关系)按一定规则拼起来,生成一个新表格
  • 不同的连接方式决定了"拼的规则"和"如何处理拼不上的行"。

1. 一般连接(条件连接)

规则 :按你指定的任意条件 (比如"相等""大于""小于"等)拼接两个表格。
例子

  • 表格R(学生表):包含"学号""姓名"列
  • 表格S(成绩表):包含"学号""成绩"列
  • 想找出成绩大于80分 的学生,用一般连接:
    R ⋈(R.学号=S.学号 AND S.成绩>80) S
    结果 :只显示学号匹配且成绩>80的学生及其成绩。
    特点 :条件灵活,用θ表示任意比较符(如=><),所以也叫"θ连接"。

2. 等值连接

规则专门用等于号(=)作为条件 的一般连接,即只拼接两表中指定列值相等 的行。
例子

  • 想拼接学生表和成绩表(按学号相等):
    R ⋈(R.学号=S.学号) S
    结果 :显示所有学号匹配的学生和成绩,但会保留两表中重复的"学号"列 (如R.学号和S.学号)。
    特点:是一般连接的特例,条件只能是"等于",结果可能有重复列。

3. 自然连接

规则

  1. 自动按两表中 名称相同的列 (如都有"学号"列)进行等值连接
  2. 自动去重 :合并重复的列名,只保留一列。
    例子
  • 学生表(学号,姓名)和成绩表(学号,成绩)做自然连接:
    R ⋈ S
    结果 :直接按"学号"相等拼接,结果列为学号、姓名、成绩 (无重复学号列)。
    特点
  • 无需手动写条件,只要列名相同就自动连接;
  • 结果更简洁,重复列只留一个。
    注意 :如果两表没有同名列,自然连接会变成笛卡尔积(所有行互相拼接),这一般不是你想要的!

4. 外连接(保留未匹配的行)

前面的连接会丢弃两表中无法匹配的行 ,而外连接会保留这些行 ,用NULL(空值)填充无法匹配的列。

1. 左外连接

规则 :保留左边表的所有行 ,右边表中无法匹配的行用NULL填充。
例子

  • 想显示所有学生(包括没成绩的):
    R 左外连接 S
    结果
    • 有成绩的学生:正常显示姓名和成绩;
    • 没成绩的学生:成绩列为NULL

2. 右外连接

规则 :保留右边表的所有行 ,左边表中无法匹配的行用NULL填充。
例子

  • 想显示所有成绩(包括没对应学生的):
    R 右外连接 S
    结果
    • 有学生的成绩:正常显示姓名和成绩;
    • 没学生的成绩:姓名列为NULL

3. 全外连接

规则 :保留左右两表的所有行 ,两边无法匹配的行都用NULL填充。
结果:相当于左外连接和右外连接的合并。

总结

连接类型 核心规则 是否保留未匹配行 重复列处理
一般连接 按任意条件(如A> B)拼接匹配行 保留所有列
等值连接 按"等于"条件拼接匹配行 保留重复列
自然连接 按同名列自动等值连接,去重重复列 去重同名列
左外连接 保留左表所有行,右表不匹配行填NULL 是(左表全保留) 同等值连接
右外连接 保留右表所有行,左表不匹配行填NULL 是(右表全保留) 同等值连接
全外连接 保留两表所有行,不匹配行填NULL 是(两表全保留) 同等值连接

二、连接查询是什么

1. 什么是连接查询?

一句话总结同时查询多个表的数据 ,就叫连接查询。

比如:想查「学生姓名」和「对应的课程成绩」,但「姓名」在学生表,「成绩」在课程表,这时候就需要把两个表「连起来」查。

2. 为什么需要连接查询?

场景举例

  • 学生表:存学生姓名、学号等信息。
  • 课程表:存学号、课程名、成绩等信息。
  • 如果想知道「张三的数学成绩」,就需要用「学号」把两个表连起来,才能拿到完整的信息。

3. 连接查询的基本结构

1. FROM子句:告诉计算机要查哪些表

sql 复制代码
SELECT ... FROM 表1, 表2;  -- 最基础的写法,用逗号分隔多个表  

注意

  • 可以是真实的表,也可以是视图(暂时先理解为"虚拟表")。

  • 表名太多时,建议用别名简化,比如:

    sql 复制代码
    SELECT ... FROM 学生表 AS s, 课程表 AS c;  -- s和c是表的别名  

2. WHERE子句:告诉计算机如何"连接"表

核心逻辑 :用一个条件,把两个表中「有关系的数据」匹配起来。
格式1:用比较运算符(最常用)

sql 复制代码
WHERE 表1.字段 = 表2.字段;  -- 最常见的是"等于"(=)  

举例:用学号连接学生表和课程表

sql 复制代码
SELECT s.姓名, c.成绩  
FROM 学生表 AS s, 课程表 AS c  
WHERE s.学号 = c.学号;  -- 连接条件:两个表的学号相等  

格式2:用BETWEEN(较少用,了解即可)

sql 复制代码
WHERE 表1.字段 BETWEEN 表2.字段1 AND 表2.字段2;  

举例:查价格在某个区间的商品(假设表1存商品名,表2存价格区间)

sql 复制代码
SELECT a.商品名  
FROM 商品表 AS a, 价格表 AS b  
WHERE a.价格 BETWEEN b.最低价格 AND b.最高价格;  

4. 连接字段的要求

  1. 类型必须可比

    • 比如两个字段都是「整数」(学号)或都是「文本」(姓名),否则无法匹配。
    • ✅ 正确:学生表.学号(整数)= 课程表.学号(整数)
    • ❌ 错误:学生表.学号(整数)= 课程表.学号(文本)
  2. 名字可以不同

    • 只要含义一致,字段名可以不一样。

    • 举例:学生表用「student_id」,课程表用「sid」,但都是学号,依然可以连接:

      sql 复制代码
      WHERE 学生表.student_id = 课程表.sid;  

5. 总结

  1. 确定要查哪些表(写在FROM后面)。
  2. 找到表之间的关联字段(比如学号、订单号等)。
  3. 用WHERE子句写出连接条件(通常是「表1.字段 = 表2.字段」)。

三、连接查询

1. 等值与非等值的连接查询

在连接查询中,根据连接条件使用的运算符不同,可分为等值连接非等值连接

  • 等值连接 :当连接条件使用"="运算符时,就叫做等值连接,这是最常用的连接方式。
  • 它的作用是把两个表中连接字段值相等的记录匹配在一起。
  • 比如,想知道每个学生的选课情况,学生信息在Student表,选课信息在SC表,就可以用学号(Sno)作为连接字段,把两个表中Sno相同的记录对应起来,查询语句如下:
sql 复制代码
SELECT Student.*, SC.*
FROM  Student, SC
WHERE Student.Sno = SC.Sno

这条语句会把Student表和SC表中Sno相等的所有记录组合展示出来,*表示显示两个表的所有列。

  • 非等值连接 :除了"="之外,使用其他运算符(如><BETWEEN等)进行连接条件判断的,就是非等值连接。例如,根据成绩区间来匹配学生和对应的课程评价,就可能用到BETWEEN等非等值运算符,但日常使用频率相比等值连接要低一些。

2. 自然连接查询

自然连接是等值连接的"升级版",它在等值连接的基础上,进一步优化了查询结果的展示。

  • 核心特点 :自然连接会自动去掉结果中重复的属性列,让查询结果更简洁清晰。
  • 比如Student表和SC表都有Sno列,自然连接后,只会显示一个Sno列。
  • 使用要点
    1. SELECT子句 :手动选择不重复的列,避免重复显示连接字段。例如查询学生及其选课信息时,只选Student.Sno,而不是同时选Student.SnoSC.Sno
    2. WHERE子句:依然要包含等值连接条件,用来匹配两个表的记录,这和等值连接的条件写法一样。
  • 示例想查询每个学生的详细信息和选修课程的课程号与成绩,使用自然连接的SQL语句如下
sql 复制代码
SELECT Student.Sno, Sname, Ssex, Sbirthdate, Smajor, Cno, Grade
FROM Student, SC
WHERE Student.Sno = SC.Sno; 

这条语句通过Student.Sno = SC.Sno进行等值连接,SELECT子句选取了不重复且需要展示的列,最终得到简洁又完整的查询结果。

3. 复合条件连接查询

在实际查询中,我们常常不仅需要连接表,还想筛选出特定条件的数据 ,这时就需要 复合条件连接查询

  • 核心原理 :在 WHERE 子句中,同时包含连接条件和选择条件 ,用 AND 连接起来。

    • 连接条件:用于匹配多个表的关联字段(和前面的等值连接类似)。
    • 选择条件:用于筛选出符合特定要求的记录(比如成绩大于90分、课程号等于某个值)。
  • 举例 :想查询选修了 81002 号课程且成绩在 90 分以上的学生学号和姓名,就需要:

    1. Student.Sno=SC.Sno 连接 Student 表和 SC 表(连接条件);
    2. SC.Cno='81002' AND SC.Grade>90 筛选出符合课程和成绩要求的记录(选择条件)。
    sql 复制代码
    SELECT Student.Sno, Sname
    FROM Student, SC
    WHERE Student.Sno=SC.Sno AND SC.Cno='81002' AND SC.Grade>90;

    这条语句会先把两个表连接起来,再筛选出同时满足三个条件的记录,最终只显示学号和姓名。

4. 自身连接查询

有时候,我们需要从 同一个表 中找出不同记录之间的关系,这时就需要 自身连接

  • 关键操作 :给同一个表起 两个不同的别名 ,让它"扮演"两个角色,区分不同记录。

    • 例如:把 Course 表命名为 ABA 代表课程本身,B 代表课程的先修课。
    • 因为属性名(如 CnoCpno)都相同,所以必须用别名前缀(A.CnoB.Cpno)明确区分。
  • 应用场景举例

    1. 查询课程的间接先修课:想知道每门课"先修课的先修课",可以用自身连接:
    sql 复制代码
    SELECT A.Cno, B.Cpno
    FROM Course A, Course B
    WHERE A.Cpno=B.Cno and B.Cpno IS NOT NULL

    这里用 A.Cpno=B.Cno 连接 AB,表示 A 的先修课是 B,再筛选出 B 还有先修课(B.Cpno IS NOT NULL)的记录。
    2. 查询选修多门课的学生 :想找出至少选修了 2 门课的学生学号,有两种方法:

    • 自身连接法 :把 SC 表命名为 AB,通过 A.Sno = B.Sno and A.Cno!= B.Cno 找出同一个学生选修的不同课程。
    sql 复制代码
    select distinct A.Sno
    from SC A, SC B
    where A.Sno = B.Sno and A.Cno!= B.Cno
    • 分组统计法 :用 GROUP BYHAVING 直接统计每个学生的选课数量。
    sql 复制代码
    select sno from sc
    group by sno having count(*)>=2

5.外连接查询

1. 外连接与普通连接的区别

  • 普通连接:只输出满足连接条件的记录(两表匹配的部分)。
  • 外连接 :除了匹配的记录,还会保留某一侧表中不满足条件的记录,未匹配的字段用 NULL 填充。

2. 外连接的类型

  • 左外连接(LEFT OUTER JOIN) :保留左表的所有记录,右表无匹配的字段填 NULL
    示例:查询所有学生及其选修课程(包括未选课的学生)

    sql 复制代码
    SELECT Student.Sno, Sname, Cno, Grade 
    FROM Student LEFT JOIN SC ON Student.Sno = SC.Sno;
    • 即使学生未选课,左表(Student)的记录也会保留,右表(SC)字段为 NULL
  • 右外连接(RIGHT OUTER JOIN) :保留右表的所有记录,左表无匹配的字段填 NULL
    示例:查询所有课程的选修成绩(包括未被选修的课程)

    sql 复制代码
    SELECT Course.Cno, Cname, AVG(Grade) AS avg_grade
    FROM Course RIGHT JOIN SC ON Course.Cno = SC.Cno
    GROUP BY Course.Cno;
    • 即使课程无人选修,右表(Course)的记录也会保留,左表(SC)字段为 NULL
  • 全外连接(FULL OUTER JOIN) :保留左右两表的所有记录,无匹配的字段填 NULL
    注意 :MySQL 不支持全外连接,可通过 UNION 合并左、右外连接结果实现。

3. MySQL 外连接语法

sql 复制代码
-- 左外连接
表1 LEFT JOIN 表2 ON 连接条件  

-- 右外连接
表1 RIGHT JOIN 表2 ON 连接条件  

6. 多表连接查询

1. 什么是多表连接?

  • 3个或以上表 进行连接查询,需至少 n-1 个连接条件(n 为表的数量)。

2. 多表连接的两种写法

  • 传统写法(逗号分隔表名,用 WHERE 指定条件)
    示例:查询学生学号、姓名、课程名及成绩

    sql 复制代码
    SELECT Student.Sno, Sname, Cname, Grade
    FROM Student, SC, Course
    WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;
  • JOIN...ON 写法(更清晰)

    sql 复制代码
    SELECT Student.Sno, Sname, Cname, Grade
    FROM Student 
    JOIN SC ON Student.Sno = SC.Sno  -- 学生表与选课表连接
    JOIN Course ON SC.Cno = Course.Cno; -- 选课表与课程表连接

3. 多表连接示例

场景:查询计算机专业学生选修"数据库系统概论"的成绩,按成绩降序排列

sql 复制代码
SELECT SC.Sno, Sname, Grade
FROM Student, SC, Course
WHERE 
  Student.Sno = SC.Sno AND  -- 学生表与选课表连接
  SC.Cno = Course.Cno AND  -- 选课表与课程表连接
  Cname = '数据库系统概论' AND  -- 筛选课程名
  Smajor = '计算机科学与技术'  -- 筛选专业
ORDER BY Grade DESC;  -- 按成绩降序

4. 多表连接的注意事项

  • 连接顺序:先连接两张表,再逐步添加其他表,避免笛卡尔积(结果行数爆炸)。
  • 别名简化 :给表起短别名(如 Student AS S),方便书写和阅读。
  • 条件完整性:确保每个表都通过连接条件关联,否则会生成无意义的笛卡尔积。

以上就是这篇博客的全部内容,下一篇我们将继续探索更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的数据库系统概论专栏
https://blog.csdn.net/2402_83322742/category_12911520.html?spm=1001.2014.3001.5482

|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |

相关推荐
️7712 分钟前
八股碎碎念02——Synchronized
java·开发语言·jvm
lzjava202412 分钟前
SQL解析工具JSQLParser
java·数据库
文牧之16 分钟前
Oracle 的 MOVE 操作是否重建表?
运维·数据库·oracle
Auc2418 分钟前
Neo4j入门第二期(Spring Data Neo4j的使用)
java·spring·neo4j
不秃的开发媛18 分钟前
JFace中MVC的表格使用介绍
java·开发语言·mvc
果冻kk30 分钟前
Java桌面应用开发详解:自制截图工具从设计到打包的全流程【附源码与演示】
java·开发语言
苏生Susheng37 分钟前
【工具类】常用的工具类——CollectionUtil
java·spring cloud·springboot·集合·软件开发·工具类·collectionutil
caihuayuan442 分钟前
Java设计模式: 工厂模式与策略模式
java·大数据·sql·spring·课程设计
Xenia22344 分钟前
JAVA05基本数据类型和包装类的转换,转换成其他数据类型,包装类与字符串的转换+学生类的定义实例
java
数据要素X1 小时前
【数据架构06】可信数据空间架构篇
大数据·运维·数据库·人工智能·架构