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

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

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

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

SELECT ... FROM1,2;  -- 最基础的写法,用逗号分隔多个表  

注意

  • 可以是真实的表,也可以是视图(暂时先理解为“虚拟表”)。
  • 表名太多时,建议用别名简化,比如:
    SELECT ... FROM 学生表 AS s, 课程表 AS c;  -- s和c是表的别名  
    

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

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

WHERE1.字段 =2.字段;  -- 最常见的是“等于”(=)  

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

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

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

WHERE1.字段 BETWEEN2.字段1 AND2.字段2;  

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

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

4. 连接字段的要求

  1. 类型必须可比

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

    • 只要含义一致,字段名可以不一样。
    • 举例:学生表用「student_id」,课程表用「sid」,但都是学号,依然可以连接:
      WHERE 学生表.student_id = 课程表.sid;  
      

5. 总结

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

三、连接查询

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

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

  • 等值连接当连接条件使用“=”运算符时,就叫做等值连接,这是最常用的连接方式。
  • 它的作用是把两个表中连接字段值相等的记录匹配在一起。
  • 比如,想知道每个学生的选课情况,学生信息在Student表,选课信息在SC表,就可以用学号(Sno)作为连接字段,把两个表中Sno相同的记录对应起来,查询语句如下:
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语句如下
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 筛选出符合课程和成绩要求的记录(选择条件)。
    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. 查询课程的间接先修课:想知道每门课“先修课的先修课”,可以用自身连接:
    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 找出同一个学生选修的不同课程。
    select distinct A.Sno
    from SC A, SC B
    where A.Sno = B.Sno and A.Cno!= B.Cno
    
    • 分组统计法:用 GROUP BYHAVING 直接统计每个学生的选课数量。
    select sno from sc
    group by sno having count(*)>=2
    

5.外连接查询

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

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

2. 外连接的类型

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

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

    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 外连接语法

-- 左外连接1 LEFT JOIN2 ON 连接条件  -- 右外连接1 RIGHT JOIN2 ON 连接条件  

6. 多表连接查询

1. 什么是多表连接?

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

2. 多表连接的两种写法

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

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

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

3. 多表连接示例

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

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

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

在这里插入图片描述

相关文章:

  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(28):ばかり
  • SQL 的 DECODE 函数
  • MacOS Docker 启动 RustDesk Server OSS
  • 多版本Node.js共存管理工具NVM详细使用教程
  • postgresql 常用参数配置
  • 第七部分:第二节 - 在 Node.js 中连接和操作 MySQL:厨房与仓库的沟通渠道
  • Postgresql 数据库体系架构
  • 从逆流监测到智慧用电:ADL200N-CT系列单相导轨表赋能家庭绿色能源
  • 储能电站:风光储一体化能源中心数字孪生
  • TiDB迁移实战:解决“Region is unavailable”报错与隐式类型转换引发的索引失效
  • PHP序列化数据格式详解
  • 多模态大语言模型arxiv论文略读(九十)
  • 【Python 基础与实战】从基础语法到项目应用的全流程解析
  • 编程技能:字符串函数10,strchr
  • php 根据另一个数组中 create_time 的时间顺序,对原始数组进行排序。
  • 计算机操作系统(十二)详细讲解调计算机操作系统调度算法与多处理机调度
  • 使用 Elasticsearch 和 Red Hat OpenShift AI 提升工作流程效率
  • 什么是VR场景?VR与3D漫游到底有什么区别
  • CustomSVG,一键生成SVG,文字秒变矢量图(WIN/MAC)
  • 阿里开源 CosyVoice2:打造 TTS 文本转语音实战应用
  • 泰安网站建设优化技术/安徽seo优化规则
  • 湖南电商平台网站建设/长春seo按天计费
  • 游戏推广方案/企业网站seo方案
  • 网站大多用源码来做吗/代运营公司
  • 做venn的网站/广告免费发布信息
  • 秦皇岛建设公司/上海seo顾问推推蛙