MySQL数据操作之多表查询——内连接、左连接、右连接、子查询

前言:本期咱们学习多表查询的内连接、左连接、右连接、子查询。

1.数据准备

-- 创建student库:student
create database student default character set utf8 collate utf8_general_ci;
/*
创建学生表:students,
学生号为Sid,数据类型为varchar(10),主键,
姓名为name,数据类型为varchar(10),
性别为sex,数据类型为varchar(1),
年龄为age,数据类型为int,
班级为class,数据类型为varchar(10),
身份证号为card,数据类型为varchar(20),
城市为city,数据类型为varchar(20)
*/
create table students(
	Sid varchar(10) primary key,
	name varchar(10),
	sex varchar(1),
	age int,
	class varchar(10),
	card varchar(20),
	city varchar(20)
);
-- 向学生表插入数据
insert into students values
('001','王昭君','女',30,'3班','634101199003157654','北京'),
('002','诸葛亮','男',29,'2班','110102199104262354','上海'),
('003','鲁班大师','男',30,'1班','820102199003047654','南京'),
('004','白起','男',35,'4班','840202198505177654','安徽'),
('005','大乔','女',28,'3班','215301199204067654','天津'),
('006','孙尚香','女',25,'1班','130502199506137654','河北'),
('007','百里玄策','男',39,'2班','140102198107277654','山西'),
('008','小乔','女',25,'3班',null,'河南'),
('009','百里守约','男',31,'1班','','湖南'),
('010','妲己','女',24,'2班','440701199607147654','广东'),
('011','廉颇','男',30,'1班','110202199005017754','北京'),
('012','孙膑','男',36,'3班','650102198401297655','新疆');
/*
创建课程表:courses
课程号为Cid,数据类型为varchar(10),主键,
课程名为Cname,数据类型为varchar(10)
*/
create table courses(
	Cid varchar(10) primary key,
	Cname varchar(10)
);
-- 向课程表插入数据
insert into courses values
('01','语文'),
('02','数学'),
('03','英语'),
('04','生物'),
('05','政治'),
('06','地理'),
('07','物理');
/*
创建分数表:scores,
学生号为Sid,数据类型为varchar(10),学生表外键,
课程号为Cid,数据类型为varchar(10),课程表外键,
分数为score,数据类型为tinyint
*/
create table scores(
	Sid varchar(10),
	Cid varchar(10),
	score tinyint,
	foreign key (Sid) references students(Sid),
	foreign key (Cid) references courses(Cid)
);
-- 向分数表插入数据
insert into scores values
('001','01',49),
('001','02',75),
('001','03',54),
('001','04',66),
('001','05',59),
('001','06',94),
('002','01',58),
('002','02',57),
('002','03',74),
('002','04',90),
('002','05',55),
('002','06',64),
('003','01',83),
('003','02',73),
('003','04',50),
('003','05',67),
('003','06',87),
('004','01',97),
('004','02',50),
('004','03',56),
('004','04',69),
('004','05',72),
('004','06',51),
('005','01',54),
('005','02',66),
('005','03',61),
('005','05',49),
('005','06',86),
('006','01',97),
('006','02',77),
('006','03',66),
('006','04',76),
('007','01',49),
('007','02',40),
('007','03',99),
('007','04',86),
('007','05',78),
('007','06',55),
('008','01',82),
('008','02',72),
('008','03',98),
('008','05',47),
('008','06',68),
('009','01',84),
('009','02',56),
('009','03',74),
('009','04',64),
('009','05',79),
('009','06',97),
('010','02',85),
('010','03',85),
('010','04',90),
('010','05',93),
('010','06',61),
('011','01',85),
('011','02',63),
('011','03',71),
('011','04',58),
('011','05',80),
('011','06',66);

2.多表查询的sql三步法

三步法:
搭框架:基本的select语句框架搭建起来,如果有多表,把相应的多表也联合进来
看条件:决定where后面的具体条件
显示的字段:select后面到底要显示什么字段
注意:如果一条select要用到多个表,表中有同名字段,就需要表名.字段名加以区分,否则就会报错

3.内连接

语法:
双表联查
select * from 表1 inner join 表2 on 表1.字段=表2.字段 where 条件 and 条件 group by 字段名 having 条件 order by 表名.字段名 desc limit;
作用:查询两个表中满足连接条件的部分
在这里插入图片描述
练习1:

-- 查询课程表信息,并显示对应成绩
select co.*,sc.score from courses co
inner join scores sc
on co.Cid=sc.Cid;

练习2:

-- 查询王昭君的信息,要求只显示姓名、课程号、成绩
select st.name,co.Cname,sc.score from students st
inner join scores sc on st.Sid=sc.Sid
inner join courses co on sc.Cid=co.Cid
where st.name='王昭君';

练习3:

-- 查询姓名为王昭君,并且成绩小于90的信息,要求只显示姓名、课程号、成绩
select st.name,co.Cname,sc.score from students st
inner join scores sc on st.Sid=sc.Sid
inner join courses co on sc.Cid=co.Cid
where st.name='王昭君' and score<90;

练习4:

-- 查询每个班级的平均成绩
select st.class,avg(sc.score) from students st
inner join scores sc on st.Sid=sc.Sid
group by st.class;

练习5:

-- 查询1班语文的平均成绩
select avg(sc.score) from students st
inner join scores sc on st.Sid=sc.Sid
inner join courses co on sc.Cid=co.Cid
where st.class='1班' and co.Cname='语文';

练习6:

-- 统计每个班级语文成绩及格的学生数量
select st.class,count(*) from students st
inner join scores sc on st.Sid=sc.Sid
inner join courses co on sc.Cid=co.Cid
where co.Cname='语文' and sc.score>=60
group by st.class;

4.左连接

语法:select * from 表1 left join 表2 on 表1.字段=表2.字段 where 条件 and 条件 group by 字段名 having 条件 order by 表名.字段名 desc limit;
作用:查询两个表中满足连接条件的部分加左表特有的部分,左表独有、右表没有的部分以null显示
在这里插入图片描述
练习1:

-- 查询所有学生的信息以及成绩,包括没有成绩的学生
select * from students st
left join scores sc on st.Sid=sc.Sid;

5.右连接

语法:select * from 表1 right join 表2 on 表1.字段=表2.字段 where 条件 and 条件 group by 字段名 having 条件 order by 表名.字段名 desc limit;
作用:查询两个表中满足连接条件的部分加右表特有的部分,右表独有、左表没有的部分以null显示
在这里插入图片描述
练习1:

-- 查询所有课程的信息,包括没有成绩的课程
select * from scores sc
right join courses co on sc.Cid=co.Cid;

6.子查询

子查询的定义:在一个select语句中,嵌入了另外一个select语句,那么被嵌入的select语句称之为子查询语句
主查询的定义:外层的第一条select语句为主查询
主查询和子查询的关系:
1、子查询是嵌入到主查询里面的
2、子查询是辅助主查询的,要么充当条件,要么充当数据源
3、子查询是可以独立存在的语句,是一条完整的select语句
4、主查询不能独立运行,依赖子查询的结果

子查询的分类:
标量子查询:子查询的返回结果只有一行一列
列子查询:子查询的返回结果是一列多行
表级子查询:子查询返回的结果是多行多列(一个表)

练习1:标量子查询

-- 查询大于平均年龄的学生记录
select * from students where age>(select avg(age) from students);

练习2:列子查询

-- 查询30岁的学生的成绩
select * from scores where Sid in (select Sid from students where age=30);

练习3:表级子查询

-- 查询所有女生的信息和成绩
select * from (select * from students where sex='女') st 
inner join scores sc on st.Sid=sc.Sid;
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值