从入门到精通MySQL联合查询

2025-07-02 17:50

本文主要是介绍从入门到精通MySQL联合查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下...

摘要

前面我们学习了数据库设计时要满足三大范式,也就意味着数据会被拆分到许多张表中,当我们想查询一个学生的基本信息与成绩时,此时就会涉及到学生表,班级表,成绩表等多张数据表,但我们给用户展示信息时并不会把冗余的数据也展示给用户,所以我们就需要用到联合查询从多张表中查询出有用的数据。此时的‘联合’,就是指多张数据表的组合。

1. 多表联合查询时MySQL内部原理

当我们进行多表联合查询时,MySQL内部会进行以下操作:

参与查询的所有表取笛卡尔积,结果集在临时表中

从入门到精通MySQL联合查询

观察哪些记录是有效数据,根据两个表的关联关系过滤掉无效数据

从入门到精通MySQL联合查询

=======================================================================
首先我们要构造一个练习数据

create database if not exists test; -- 创建库
use test;
-- 课程表
create table if not exists course(
  id bigint primary key auto_increment,
  `name` varchar(20) not null
);
insert into course (name) values ('Java'), ('C++'), ('MySQL'), ('操作系统'), ('计
算机网络'), ('数据结构');
-- 学生表
create table if not exists student(
  id bigint primary key auto_increment,
  `name` varchar(20),
  sno varchar(20),
  age bigint,
  gender bigint,
  enroll_date varchar(20),
  class_id bigint
);
insert into student (name, sno, age, gender, enroll_date, class_id) values
('唐三藏', '100001', 18, 1, '1986-09-01', 1),
('孙悟空', '100002', 18, 1, '1986-09-01', 1),
('猪悟能', '100003', 18, 1, '1986-09-01', 1),
('沙悟净', '100004', 18, 1, '1986-09-01', 1),
('宋江', '200001', 18, 1, '2000-09-01', 2),
('武松', '200002', 18, 1, '2000-09-01', 2),
('李逹', '200003', 18, 1, '2000-09-01', 2),
('不想毕业', '200004', 18, 1, '2000-09-01', 2);
-- 班级表
create table if not exists class(
  id bigint primary key auto_increment,
  `name` varchar(20)
);
insert into class(name) values ('Java001班'), ('C++001班'), ('前端001班');
-- 分数表
create table if not exists score(
  id bigint primary key auto_increment,
  score bigint,
  student_id bigint,
  course_id bigint
);
insert into score (score, student_id, course_id) values
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
(60, 2, 1),(59.5, 2, 5),
(33, 3, 1),(68, 3, 3),(99, 3, 5),
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
(81, 5, 1),(37, 5, 5),
(56, 6, 2),(43, 6, 4),(79, 6, 6),
(80, 7, 2),(92, 7, 6);

Navicat可视化图:

班级表

从入门到精通MySQL联合查询

课程表

从入门到精通MySQL联合查询

分数表

从入门到精通MySQL联合查询

学生表

从入门到精通MySQL联合查询

✏️1.1 实例:一个完整的联合查询过程

查询学生姓名为孙悟空的详细信息,包括学生个人信息和班级信息

  1. 首先确定参与查询的表,分别是student表与class表
select * from student,class;

从入门到精通MySQL联合查询

  1. 确定连接条件,条件为student表中的class_id要与class表中的id相等
select * from student,class where student.class_id = class.id;

从入门到精通MySQL联合查询

  1. 加入查询条件
select * from student,class where student.class_id = class.id and student.`name` = '孙悟空';

从入门到精通MySQL联合查询

  1. 精减查询结果字段
select
 student.id,
 student.name,
 class.name
from 
  student,class 
where
  student.class_id = class.id 
and 
  student.`name` = '孙悟空';

从入门到精通MySQL联合查询

  1. 可以为表名指定别名
select
 stu.id,
 stu.name,
 c.name
from 
  student as stu,class as c
where
  stu.class_id =c.id 
and 
  stu.`name` = '孙悟空';

2. 内连接

select * from 表名1 as 别名1 , 表名2 as 别名2 where 连接条件 and 其他条件;
  1. 查询"唐三藏"同学的成绩
-- 查询唐三藏同学的成绩
select
 student.`name`,score.score,course.`name` 
 from
  student,score,course 
 where
  student.id = score.student_id 
 and
  score.course_id = course.id 
 and
  student.`name` = '唐三藏';

从入门到精通MySQL联合查询

  1. 查询所有同学的总成绩,及同学的个人信息
  select 
    student.`name`,sum(score.score) as '总分'
  from 
    student,score
  where
    student.id = score.student_id
  group by 
    `name`;

从入门到精通MySQL联合查询

  1. 查询python所有同学每门课的成绩,及同学的个人信息
select
 student.`name`,score.score,course.`name`
 from
 student,score,course 
 where 
 student.id = score.student_id 
 and 
 score.course_id = course.id;

从入门到精通MySQL联合查询

3. 外连接

外连接分为左外连接、右外连接和全外连接三种类型,因为MySQL不支持全外连接,所以本文不再介绍外连接部分。
• 左外连接:返回左表的所有记录和右表中匹配的记录。如果右表中没有匹配的记录,则结果集中对
应字段会显示为NULL。
• 右外连接:与左外连接相反,返回右表的所有记录和左表中匹配的记录。如果左表中没有匹配的记
录,则结果集中对应字段会显示为NULL。

-- 左外连接,表1完全显⽰
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显⽰
select 字段 from 表名1 right join 表名2 on 连接条件;
  1. 查询没有参加考试的同学信息
select * from student left join score on student.id = score.student_id where score.score is null;

从入门到精通MySQL联合查询

  1. 查询没有学生的班级
select * from student right join class on class.id = student.class_id where student.id is null;

从入门到精通MySQL联合查询

4. 自连接

自连接是自己与自己取笛卡尔积,可以把行转化成列,在查询的时候可以使用where条件对结果进行过滤,以至于实现行与行之间的比较,在做自连接时要为表起别名(否则报错)。

--不为表指定别名
mysql> select * from score, score;
ERROR 1066 (42000): Not unique table/alias: 'score'
--指定别名
mysql> select * from score s1, score s2;
  1. 显示所有"MySQL"成绩比"JAVA"成绩高的成绩信息
select s1.student_id as '学生',s1.score as 'MySQL',s2.score as 'JAVA' from (select * from score where  course_id = 3) as s1 ,(select * from score where course_id = 1 ) as s2 where s1.student_id = s2.student_id and s1.score > s2.score;

思路China编程:先查出JAVA的成绩,在查出MYSQL的成绩,两张表分别各自包含JAVA和MYSQL成绩,然后进行连接,连接条件为表一与表二学生id相同,限制条件为MYSQL成绩大于JAVA成绩

从入门到精通MySQL联合查询

5. 子查询

子查询是把⼀个SELECT语句的结果当做别一个SELECT语句的条件,也叫嵌套查询。

select * from table1 where condition [= |in](select * from where (......))
✏️5.1 单行子查询

示例: 查询与"不想毕业"同学的同班同学

select student.`name`,student.class_id 
  from 
    student  
  where 
    class_id   = (select class_id from student where `name` = '不想毕业' ) 
  and 
    `name` != '不想毕业';

从入门到精通MySQL联合查询

✏️5.2 多行子查询

示例:查询"MySQL"或php"Java"课程的成绩信息

select * from score where course_id in (select course.id from course where `name` = 'Java' or `name` = 'MySQL');

从入门到精通MySQL联合查询

使用 not in 可以查询除了"MySQL"或"Java"课程的成绩

✏️5.3 多列子查询

单行子查询和多行子查询都只返回一列数据,多列子查询中可以返回多个列的数据,外层查询与嵌套的内层查询的列要匹配

示例:查询重复录入的分数

select *  from score where (score,student_id,course_id) in (select score,student_id,course_id from score group by score,student_id,course_id having count(*)>1);

从入门到精通MySQL联合查询

✏️5.4 在from子句中使用子查询

当⼀个查询产生结果时,MySQL自动创建一个临时表,然后把结果集放在这个临时表中,最终返回
给用户,在from子句中也可以使用临时表进行子查询或表连接操作

示例:查询所有比"Java001班"平均分高的成绩信息

select * from score as s ,(select avg(score) as avg_score from score where student_id in ( select student_id from student where class_id = 1))  as tmp where s.score > tmp.avg_score;

从入门到精通MySQL联合查询

6. 合并查询

为了合并多个select操作返回的结果,可以使⽤集合操作符 union,union all

-- 创建⼀个新表并初始化数据
 create table student1 like student;
 
insert into student1 (name, sno, age, gender, enroll_date, class_id) values
('唐三藏', '100001', 18, 1, '1986-09-01', 1),
('刘备', '300001js', 18, 1, China编程'1993-09-01', 3),
('张⻜', '300002', 18, 1, '1993-09-01', 3),
('关⽻', '300003', 18, 1, '1993-09-01', 3);
✏️6.1 union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

示例:查询student表中 id < 3 的同学和student1表中的所有同学

select * from student where id<3 union select * from student1;

从入门到精通MySQL联合查询

✏️6.2 union all

该操作符⽤于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

示例:查询student表中 id < 3 的同学和student1表中的所有同学

select * from student where id<3 union all select * from student1;

从入门到精通MySQL联合查询

7. 插入查询结果

insert into 表名(列名1,列名2) select .....

示例:将student表中C++001班的学生复制到student1表中

insert into student1 (name, sno, age, gender, enroll_date, class_id)
select s.name, s.sno, s.age, s.gender, s.enroll_date, s.class_id
from student s, class c where s.class_id = c.id and c.name = 'C++001班';

从入门到精通MySQL联合查询

到此这篇关于从入门到精通MySQL联合查询的文章就介绍到这了,更多相关mysql联合查询内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于从入门到精通MySQL联合查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155275

相关文章

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二