思路:首先可以根据java语言这个课程名在课程表里找到它所对应的课程号,
然后根据课程号在成绩表里找到它对应的成绩,求平均值
select avg(cj) from cjb where kch=(
select kch from kcb where kcm='java语言'
);
思路:要在cjb里找到特定的成绩,需要相应的xh和kch,
xh可以通过1班张三在xsb里定位到,
kch可以通过java语言在kcb里定位到,
select cj
from cjb
where xh=(
select xh from xsb where bj='1班' and xm='张三'
)
and kch=(
select kch from kcb where kcm='java语言'
);
将多张表(两张及其以上的表)联接成一张大的表,然后从表中查询特定的数据
引入:查询张三同学的各科成绩,要求显示的字段有姓名、课程号和成绩
问题:不在一张表的字段信息要能在一张表里显示,可以通过关联查询解决这个问题
表和表之间是如何关联的?——》通过笛卡儿积运算(将两张表里任意两条记录组合在一起形成新
的记录,最终生成一张大的表的过程)
将学生表和成绩表做笛卡儿积运算:
select * from xsb,cjb;
select * from xsb cross join cjb;
生成一张大的表:
11列(8+3)132行(11*12)
xsb:8列11行
cjb:3列12行
笛卡儿积运算虽然能将两张表关联在一起生成一张大的表,但是这张大的表里存在许多的
没有意义的垃圾数据(例如张三学员信息会关联非张三学员的成绩)——》那么如何过滤这些垃圾数据呢?
——》通过添加关联条件进行垃圾数据的消除——》我们希望张三的学员信息联接张三的各科成绩,
可以通过让学生表的学号和成绩表的学号相等来过滤垃圾数据。
select * from xsb,cjb
where xsb.xh=cjb.xh;
内联接还有一种写法:
select * from xsb inner join cjb
on(xsb.xh=cjb.xh);
回到最开始的查询需求:
select xsb.xm,cjb.kch,cjb.cj
from xsb,cjb
where xsb.xh=cjb.xh
and xsb.xm='张三';
注解:
(1)只要看到了from后面跟了两张或以上的表,就要反应出这是在做笛卡儿积运算,
笛卡儿积运算会产生垃圾数据,需要添加关联条件来消除垃圾数据;
(2)如果题目的需求除了多表关联以外还有其它的限定条件,我们可以通过and连接
其他的条件;
(3)在关联查询中,如果涉及到同名字段,一定要加上表名做前缀,否则会报错,对于
初学者建议在写关联查询的SQL时所有的字段都带上表名做前缀,这样不容易出错。
(4)除了可以给字段取别名之外,还可以给表取别名:
select x.xm,c.kch,c.cj
from xsb x,cjb c
where x.xh=c.xh
and x.xm='张三';
关联查询有多种:
内联接:只返回满足关联条件的结果集
外联接:
(1)左外联接:
指的是除了返回满足关联条件的结果集以外,还会把左边的那张表完整的展示出来,
右边的那张表不满足关联条件的字段位置补空值(null)
(2)右外联接:
指的是除了返回满足关联条件的结果集以外,还会把右边的那张表完整的展示出来,
左边的那张表不满足关联条件的字段位置补空值(null)
(3)全外联接:
指的是除了返回满足关联条件的结果集以外,还会把两边的表完整的展示出来,
两边不满足关联条件的字段位置补空值(null)
示例:查询所有学员的课程号、学号、姓名、成绩(要求没有成绩的学员信息也要展示出来)
select cjb.kch,xsb.xh,xsb.xm,cjb.cj
from xsb,cjb
where xsb.xh=cjb.xh;
以上这种写法不能将没有成绩的学员信息展示出来(例如 李晨)
可以通过左外联接或者右外联接来实现这个需求(将所有学员信息展示)。
左外联接:
select cjb.kch,xsb.xh,xsb.xm,cjb.cj
from xsb left join cjb
on(xsb.xh=cjb.xh);
右外联接:
select cjb.kch,xsb.xh,xsb.xm,cjb.cj
from cjb right join xsb
on(xsb.xh=cjb.xh);
全外联接:通常使用full join来实现,但是mysql不支持full join,
那么可以通过union集合操作来实现全外联接:
select cjb.kch,xsb.xh,xsb.xm,cjb.cj
from xsb left join cjb
on(xsb.xh=cjb.xh)
union
select cjb.kch,xsb.xh,xsb.xm,cjb.cj
from xsb right join cjb
on(xsb.xh=cjb.xh);
三张表关联的示例:
查询学生的姓名、选修的课程名和成绩
select x.xm,k.kcm,c.cj
from xsb x,cjb c,kcb k
where x.xh=c.xh
and c.kch=k.kch;
select x.xm,k.kcm,c.cj
from xsb x inner join cjb c on(x.xh=c.xh)
inner join kcb k on(c.kch=k.kch);
查询java语言课程和数据库的学员的名字和成绩
select x.xm,c.cj
from xsb x,cjb c
where x.xh=c.xh
and c.kch in(select kch from kcb where kcm in('java语言','数据库'));