MySQL联合查询详细示例代码

 更新时间:2025年10月22日 11:35:31   作者:苏小瀚  
MySQL联合查询是数据库操作中十分重要的技能之一,它允许用户从多个表中提取并组合数据,下面这篇文章主要介绍了MySQL联合查询的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1. 联合查询的由来

因为我们在创建数据表时候遵循范式的规则,将数据拆分成多个表,而我们想要查询表的所有属性列,就需要将几张表的数据结合起来显示,因此就产生了联合查询。比如:学生表和课程表,这里我们想要在一张表中显示学生表和课程表的信息,就需要用到联合查询。    

2. 笛卡尔积

2.1 理论介绍

数据库中笛卡尔积指的是两个表之间的运算,我们可以将两个表进行笛卡尔积就能得到两个表的完整信息。

对下面这两个表进行笛卡尔积的运算:

得到的结果表是:

两个表通过笛卡尔积得到的 表的行数是两个表行数的乘积,表的列数是两个表列数的和。

我们观察新得到的表会发现这张表里面有很多无效数据,也就是张三应该是一班的,所以第二行是无效数据,那我们会发现无效数据是两个班级id不相同的数据,那我们在查询的时候可以添加一个where条件。

如何区分两个班级id呢?

我们可以这样表示 student.id 和 class.id。通过成员访问运算符 . 来实现。

2.2 SQL语句编写

下面是联合查询的代码实现:

create table class1(class_id int primary key, class_name varchar(20));
insert into class1 values(1,'一班'), (2,'二班');

create table student1(id int primary key, name varchar(20), gender varchar(10), class_id int, foreign key (class_id) references class1(class_id));
insert into student1 values(1,'张三','男',1), (2,'李四','男',1),(3,'王五','女',2);

select * from student1, class1 where student1.class_id = class1.class_id;

查询结果为:

2.3 联合查询的流程

  1. 我们先对两个表进行笛卡尔积。
  2. 接着添加连接条件。
  3. 然后根据需求添加其他条件。
  4. 最后针对列进行筛选/计算表达式/聚合查询等操作。

下面我举几个例子,帮助理解联合查询的流程:

首先我们先准备几张表进行查询,下面有学生表,班级表,成绩表,课程表四张表:

create table student(student_id int primary key auto_increment, name varchar(20), sno varchar(20), age int, gender int, enroll_date datetime, class_id int, foreign key (class_id) references class(class_id));
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 class(class_id int primary key auto_increment, name varchar(20));
insert into class(name) values('001班'), ('002班'), ('003班');

create table course(course_id int primary key auto_increment, name varchar(20));
insert into course(name) values('Java'),('C++'),('MySQL'),('操作系统'),('计算机网络'),('数据结构');

create table score(score double, student_id int, course_id int, primary key(student_id,course_id));
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);

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

1. 我们确定要查询的表来自那几张表,进行笛卡尔积运算。

学生表,班级表

select * from student, class;

2. 确认连接条件,进行查询。

select * from student, class where student.class_id = class.class_id;

3. 根据需求进一步增加条件。

select * from student, class 
where student.class_id = class.class_idand student.name = '孙悟空';

4. 根据需求来查找对应的列。

select student.name, student.sno, student.age, student.gender, student.enroll_date, class.name as '班级名称' 
from student,class 
where student.class_id = class.class_id and student.name = '孙悟空';

2.4 内连接

内连接相当于在原来的联合查询的语句上进行修改,这里用到 join on两个关键字。

原来查询是:

select * from student, class where student.class_id = class.class_id;

改为内连接为:

select * from student join class on student.class_id = class.class_id;

这两个SQL语句查询出来的内容都是一样的。

我们可以将上面的联合查询语句改成:

#内连接
# 1.笛卡尔积
select * from student join class;
# 2.添加连接条件
select * from student join class on student.class_id = class.class_id;
# 3.进一步添加条件
select * from student join class on student.class_id = class.class_id
where student.name = '孙悟空';
# 4.对列进行精简
select student.name, student.sno, student.age, student.gender, student.enroll_date, class.name
from student join class on student.class_id = class.class_id
where student.name = '孙悟空';

查询所有同学的总成绩和同学的个人信息。

确认从学生表和成绩表中查找。

# 笛卡尔积
select * from student join score;
# 添加连接条件
select * from student join score on student.student_id = score.student_id;
# 没有条件添加
#对列进行精简
select student.name, sum(score.score) as total_score
from student join score on student.student_id = score.student_id 
group by student.name;

查询所有同学每门课的成绩,及同学的个人信息。

确认从学生表,成绩表 和课程表中查找:

# 笛卡尔积
select * from score join student join course;
# 添加连接条件
select * from score 
join student on student.student_id = score.student_id
join course on course.course_id = score.course_id;
#没有条件进行添加
#对列进行精简
select student.name, course.name as course_name, score.score
from score
join student on student.student_id = score.student_id
join course on course.course_id = score.course_id;

2.5 外连接

外连接分为左外连接,右外连接,全外连接,mysql不支持全外连接。

左外连接:如果左边表的数据在右边表中没有匹配记录,那么就会将对应右边记录为null。

右外连接:如果右边表对应左边表数据没有匹配记录,那么就会将对应左边记录为null。

全外连接:左右两张表互相存在不对应的匹配数据,就会为null。

创建新的两张表,学生表和成绩表:

create table student(id int, name varchar(20));
insert into student values(1,'张三'), (2,'李四'), (3,'王五');

create table score(student_id int, score int);
insert into score values(1,88), (2,99), (4,77);

内连接:

select * from student, score where student.id = score.student_id;

左外连接:

select * from student left join score on student.id = score.student_id;

右外连接:

select * from student right join score on student.id = score.student_id;

2.6 自连接

自连接是表自己对自己进行连接,我们可以把行变换成列,而列跟列之间能进行比较,所以相当于间接实现了行与行进行比较。我们在表连接时候,要为表起两个不同的别名。

显示所有"MySQL"成绩比"JAVA"成绩高的成绩信息:

这里我们是用成绩表进行自连接查询:

select s1.student_id, s1.course_id, s1.score, s2.course_id, s2.score
from score as s1, score as s2 
where s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1 and s1.score > s2.score;

2.7 子查询

子查询通常是把一个SQL语句的结果当作另一个SQL语句的条件来进行查询的。

但是这种查询方式比较难以阅读,违背软件开发的核心原则(将大问题转换为多个小问题),很少使用。

单行子查询:

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

select name from student where class_id = 
(select class_id from student where name = '不想毕业');

多行子查询:

查询mysql或Java课程的成绩信息:

select course_id,score from score where course_id in (
select course_id from course where name = 'MySQL' or name = 'Java');

多列子查询:

查询重复录入的分数:

 select * form 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(0) > 1);

2.8 合并查询

这里我们可以将多个查询结果合并在一起进行,使用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), 
('刘备', '300001', 18, 1, '1993-09-01', 3), 
('张飞', '300002', 18, 1, '1993-09-01', 3),
('关羽', '300003', 18, 1, '1993-09-01', 3);

union操作符:

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

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

查询结果:

这里得union会把两个查询的结果取并集,并且会自动取出重复的行。

union all操作符:

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

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

查询结果:

union all查询时候查询两个结果的并集,不会去除重复的行。

2.9 插入查询结果

将student表中的001班的学生复制到student1表中:

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

这里后面的查询出来的条件应该与前面的条件类型和数量对应。

总结

到此这篇关于MySQL联合查询的文章就介绍到这了,更多相关MySQL联合查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL表空间传输秒级迁移大表的操作方法

    MySQL表空间传输秒级迁移大表的操作方法

    本文给大家介绍MySQL表空间传输秒级迁移大表的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-09-09
  • Windows中Mysql启动失败的完美解决方案

    Windows中Mysql启动失败的完美解决方案

    这篇文章主要介绍了Windows中Mysql启动失败解决方案,mysql服务启动失败分为2种情况给大家详细介绍,针对每一种给大家详细解决,需要的朋友可以参考下
    2022-10-10
  • 并发环境下mysql插入检查方案

    并发环境下mysql插入检查方案

    这篇文章主要介绍了并发环境下mysql插入检查方案的相关资料,需要的朋友可以参考下
    2016-03-03
  • 解决phpstudy无法启动MySQL服务的三种方法小结

    解决phpstudy无法启动MySQL服务的三种方法小结

    本文主要介绍了光速解决phpstudy无法启动MySQL服务的三种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • 基于SQL中SET与SELECT赋值的区别详解

    基于SQL中SET与SELECT赋值的区别详解

    本篇文章是对SQL中SET与SELECT赋值的区别进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL忘记root密码的两种解决方案

    MySQL忘记root密码的两种解决方案

    在使用MySQL数据库管理系统时,有时候会碰到忘记了root用户的密码的情况,这时候就需要找到一种解决方案来重置或者恢复root密码,本文将介绍两种常用的方法来解决这个问题,需要的朋友可以参考下
    2024-09-09
  • MySQL性能调优之索引与参数调优实践指南

    MySQL性能调优之索引与参数调优实践指南

    在高并发,海量数据场景下,MySQL数据库性能直接影响业务体验和系统稳定性,本文主要来和大家讲讲MySQL索引与查询参数调优技巧,希望对大家有所帮助
    2025-07-07
  • MySQL逻辑架构与常用的存储引擎方式

    MySQL逻辑架构与常用的存储引擎方式

    这篇文章主要介绍了MySQL逻辑架构与常用的存储引擎方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • MYSQL 解锁与锁表介绍

    MYSQL 解锁与锁表介绍

    相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制
    2017-04-04
  • 从零开始学习SQL查询语句执行顺序

    从零开始学习SQL查询语句执行顺序

    sql语言中的查询的执行顺序,以前不是很了解,最近查阅了相关资料,在sql语言中,第一个被处理的字句总是from字句,最后执行的limit操作,现在小编来和大家一起学习一下
    2019-05-05

最新评论