数据库多表链接查询的方式

多表联查可以通过连接运算实现,即将多张表通过主外键关系关联在一起进行查询。

分为非等值查询和等值查询:

需要用到的表: 

学生表:
create table student(
	sid int(11),
	sname varchar(10),
	birthday datetime,
	ssex varchar(10),
	classid int(11)
)

成绩表:
create table sc(
	sid int(11),
	cid int(11),
	score decimal(18,1)
)

课程表:
create table course(
	cid int(11),
	cname varchar(10),
	tid varchar(10)
)

班级表:
create table class(
	classid int(11),
	classname varchar(20)
)

老师表:
create table teacher(
	tid int(11)primary key,
	tname varchar(10),
	tsex tinyint(4),
	tbirthday date,
	taddress varchar(255),
	temail varchar(255),
	tmoney decimal(20,2)
)

 

 1.非等值查询(不属于内联):

语法:

select * from 表1,表2

举例(学生表的数据*班级表的数据*成绩表的数据的数量):

select count(*) from stuednt,class,sc

如上实例,此查询方式的实质是笛卡尔积的应用,若学生表有5行,班级表有2行,成绩表有10行,上例的查询结果便是5*2*10=100行数据。

不推荐使用非等值查询方式,因为当数据量庞大时,使用此方式便会造成大量的数据,从而降低效率。故此方式适用于数据量较小的情况。

 2.等值联查(内联查询): 

语法:

select * from 表1,表2 where 表1.字段1 = 表2.字段2......

举例:

select * from student,class where student.classid = class.classid

通过where后面的判断条件来获取需要的数据,主要分为以下三种(内连接、左连接、右连接):

①内联:inner join 

侧重于两个表之间的共性,它的作用是使用链接比较两个或多个表之间的共有数据,然后进行返回。

语法:

select * from 表1
inner join 表2
on 表1.字段名 = 表2.字段名

举例(比如要查询学生的成绩,涉及到两张表:学生表和成绩表,使用内连接查询的数据就是下图红色部分)

select * from student
inner join sc on student.sid=sc.sid

延伸举例(五表联查)

select *from student
inner join sc on student.sid=sc.sid
inner join course on sc.cid=course.cid
inner join teacher on course.tid=teacher.tid
inner join class on student.classid=class.classid

②左外联:left join 

以left join 左边的表(表1)为主表,从左表中返回所有的记录,即便在右表(表2)中没有匹配的行。

on的后面,根据条件进行过滤筛选,再生成临时查询结果。

where的后面,从临时查询结果中再根据条件进行筛选,生成最终结果。

语法:

select * from 表1
left join 表2
on 表1.字段1=表2.字段1

举例(使用左连接查询的数据就是下图红色部分):  

 

select * from student 
left join class 
on student.classid=class.classid

 如果是三张表,可以通过两个 left join 来连接,即把前面两张表先 left join 之后当成一张虚拟表,然后再跟第三张表 left join。

③右外联:right join 

以left join 右边的表(表2)为主表,从右表中返回所有的记录,即便在左表(表1)中没有匹配的行。

语法:

select * from 表1
right join 表2
on 表1.字段1=表2.字段1

举例(使用右连接查询的数据就是下图红色部分):  

 

select * from student 
right join class 
on student.classid=class.classid

3.举例一些考试的题:

* 根据上面的表结构找到语文分数相同的学生的个数

select score,count(*) from sc 
where course=‘语文’
group by score 
having count(*) >= 2

查询平均成绩大于70的学生姓名

select sname from sc 
group by sname 
having avg(score) > 70

 * 查询出每门课都大于80分的学生的姓名

select sname from student 
where sid not in
 (select  sid  from sc where score < 80)

 * 查询数学成绩最好的学生姓名

select sname from student,sc 
where student.sid = sc.sid and 
 cid = (select cid from course where cname = '数学')
 order by score desc limit 1

* 查询各科成绩平均分,显示课程名称和平均分并按照平均分降序排序 

select cname, avg(score) 平均分 from course,sc 
where course.cid = sc.cid 
group by course.cid 
order by 平均分 desc

* 查询考试超过2门不及格学生的平均成绩 

select avg(score) from sc where sid in
 (select sid from sc where score < 60 group by sid having count(*) >=2)

4.拓展发散:

因为举例中有用到子查询,所以简单写一下:子查询和关联查询的区别

子查询就是查询中又嵌套的查询,表连接都可以用子查询,但不是所有子查询都能用表连接替换,子查询比较灵活,方便,形式多样,适合用于作为查询的筛选条件,而表连接更适合与查看多表的数据。
子查询不一定需要两个表有关联字段,而连接查询必须有字段关联(所谓的主外键关系)
①表关联的效率要高于子查询,因为子查询走的是笛卡尔积
②表关联可能有多条记录,子查询只有一条记录,如果需要唯一的列,最好走子查询

对于数据量多的肯定是用连接查询快些,因为子查询会多次遍历所有的数据(视你的子查询的层次而定),而连接查询只会遍历一次。

但是数据量少的话也就无所谓是连接查询还是子查询,视自己的习惯而定。一般情况下还是用子查询来的好,容易控制。

预祝大家早日成为代码小能手!!!

 

 

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值