作者简介
马听,多年 DBA 实战经验,对 MySQL、 Redis、ClickHouse 等数据库有一定了解,专栏《一线数据库工程师带你深入理解 MySQL》、《Redis 运维实战》作者。
1 数据准备
建表及数据准备,以便后面 SQL 练习:
代码语言:javascript复制use yzl; /* 使⽤用yzl这个database */
drop table if exists student_info; /* 如果表student_info存在则删除表student_info */
CREATE TABLE `student_info` ( /* 创建表student_info */
`id` int(11) NOT NULL auto_increment,
`stu_id` int(11) DEFAULT NULL COMMENT '学生ID',
`stu_name` varchar(30) DEFAULT NULL COMMENT '学生姓名',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时
间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP
COMMENT '记录更新时间',
PRIMARY KEY (`id`),
KEY `idx_stu_id` (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
drop table if exists student_score; /* 如果表student_score存在则删除表 student_score */
CREATE TABLE `student_score` ( /* 创建表student_score */
`id` int(11) NOT NULL auto_increment,
`stu_id` int(11) DEFAULT NULL COMMENT '学生ID',
`stu_score` int(11) DEFAULT NULL COMMENT '学生分数',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时
间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP
COMMENT '记录更新时间',
PRIMARY KEY (`id`),
KEY `idx_stu_id` (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into student_info(stu_id,stu_name) values(1,'zhang'),(2,'wang'),
(3,'zhao');
insert into student_score(stu_id,stu_score) values(1,88),(2,90),(3,92);
2 查看所有数据
查出所有数据,以方便跟后续 SQL 结果做对比:
代码语言:javascript复制select * from student_info;
代码语言:javascript复制select * from student_score;
3 子查询
3.1 子句结果只匹配一条数据的情况
代码语言:javascript复制select * from student_info where stu_id = (select stu_id from student_score where stu_score = 90);
3.2 子句结果匹配多行数据的情况
代码语言:javascript复制select * from student_info where stu_id in (select stu_id from student_score where stu_score >=90);
4 关联查询
4.1 内连接(inner join)
代码语言:javascript复制select a.stu_id,a.stu_name,b.stu_score from student_info a inner join student_score b on a.stu_id= b.stu_id;
可以看出,在内连接中,只有满足条件(两表 id 相等)的数据才会出现。
在练习左连接和右连接之前,为了显示出两者的区别,这里再在每张表中新增一条记录,两张表中的这两条记录 stu_id 不相等。
代码语言:javascript复制insert into student_info(stu_id,stu_name) values(4,'liu');
insert into student_score(stu_id,stu_score) values(5,80);
然后再查询两张表的总数据,方便后面对比:
代码语言:javascript复制select * from student_info;
select * from student_score;
4.2 左连接(left join)
代码语言:javascript复制select * from student_info a left join student_score b on a.stu_id = b.stu_id;
可以看出,左连接查询的结果为左表的全部记录,即使右表中没有对应的匹配记录
4.3 右连接(right join)
代码语言:javascript复制select * from student_info a right join student_score b on a.stu_id = b.stu_id;
可以看出,右连接查询的结果为右表的全部记录,即使左表中没有对应的匹配记录。