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

[MySQL] 联合查询

目录

1. 联合查询的由来

2. 笛卡尔积

2.1 理论介绍

2.2 SQL语句编写

2.3 联合查询的流程

2.4 内连接

2.5 外连接

2.6 自连接

2.7 子查询

2.8 合并查询

2.9 插入查询结果


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班';

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

http://www.dtcms.com/a/513333.html

相关文章:

  • 黑客马拉松竞赛中产品成功要素与商业价值实现[特殊字符]
  • 做物流网站的公司网络规划设计师报名
  • 网站项目建设的必要性德国红点设计奖官网
  • 能支持微信公众号的网站建设网站策划的重要性
  • 佛山营销手机网站建设白沟网站开发
  • 复习MySQL
  • 包头网站开发建设电商设计灵感网站
  • 临沂百度网站互联网建站公司
  • 流行的企业网站推广现在注册公司好注册吗
  • 做漂亮的网站dede能建立手机网站吗
  • 文山 网站建设 滇icp网站建设报价单及项目收费明细表
  • wordpress 合并js网站优化方案书
  • .net购物网站开发龙岗做网站公司icxun
  • 一个网站多少钱?清华大学精品课程网站
  • 亚马逊网站联盟gif制作软件app
  • 新加坡房产网站大全天津建设合同怎么在网站录入
  • mysql和tbase语法转换(已亲测)
  • 高端设计网站都有哪些自助设计网站
  • 专业建站公司设计方案无锡网站制作咨询
  • 网站开发的大学生应届简历手机短视频网站的建设
  • 数据结构——广度优先搜索
  • 网站建设教程 作业黄冈黄页
  • 潍城区住房和城乡建设局网站网站怎么做中英文交互
  • 厨房电子秤方案:厨房秤常规的功能有那些?
  • 旅游景点网站模板大全哪家网站开发培训好
  • FontBook for mac字体管理工具
  • 网站聚合页面芙蓉区建设局网站
  • 美容店网站建设网站做海康直播
  • 网站如何做留言板mxd 主题Wordpress
  • 为什么里程碑设置不清晰会拖慢进度